Skip to content

Instantly share code, notes, and snippets.

@maiconrs95
Last active March 28, 2024 18:56
Show Gist options
  • Save maiconrs95/1d6dbf29474b7a3a1b2dfae744c63b90 to your computer and use it in GitHub Desktop.
Save maiconrs95/1d6dbf29474b7a3a1b2dfae744c63b90 to your computer and use it in GitHub Desktop.
Custom react -router query params management
import { useCallback } from 'react';
import { useSearchParams } from 'react-router-dom';
type Value = string | number;
type Query = {
key: string;
value?: Value;
};
type Queries = Query[];
type Result = [getter: URLSearchParams, setter: (data: string | Queries, value?: Value) => void];
const isQueries = (data: string | Queries): data is Queries => Array.isArray(data);
const isValue = (value?: Value): value is string | number =>
(typeof value === 'string' && Boolean(value.length)) || typeof value === 'number';
export function useUrlSearchParams(): Result {
const [search, setSearch] = useSearchParams();
const setQuery = useCallback(
(data: string | Queries, value?: Value) => {
setSearch((state) => {
if (isQueries(data)) {
data.forEach(({ key, value }) => {
if (isValue(value)) {
state.set(key, value?.toString());
} else {
state.delete(key);
}
});
} else {
if (isValue(value)) {
state.set(data, value?.toString());
} else {
state.delete(data);
}
}
return state;
});
},
[setSearch],
);
return [search, setQuery];
}
export default function useSearchParamsV5(): Result {
const { search } = useLocation();
const history = useHistory();
const query = React.useMemo(() => new URLSearchParams(search), [search]);
const setQuery = React.useCallback(
(data, value) => {
if (isQueries(data)) {
data.forEach(({ key, value }) => {
if (isValue(value)) {
query.set(key, value?.toString());
} else {
query.delete(key);
}
});
} else {
if (isValue(value)) {
query.set(data, value?.toString());
} else {
query.delete(data);
}
}
history.replace({
search: query.toString(),
});
},
[query, history]
);
return [query, setQuery];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment