Extract search param handling to common hook

This commit is contained in:
Bill Thornton
2025-07-30 12:51:47 -04:00
parent 2912bf50c5
commit 357ce7c9b8
2 changed files with 50 additions and 32 deletions
+9 -32
View File
@@ -1,49 +1,26 @@
import React, { type FC, useEffect, useState } from 'react';
import type { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type';
import React, { type FC } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useDebounceValue } from 'usehooks-ts';
import { usePrevious } from 'hooks/usePrevious';
import globalize from 'lib/globalize';
import Page from 'components/Page';
import SearchFields from 'apps/stable/features/search/components/SearchFields';
import SearchSuggestions from 'apps/stable/features/search/components/SearchSuggestions';
import SearchResults from 'apps/stable/features/search/components/SearchResults';
import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type';
import SearchSuggestions from 'apps/stable/features/search/components/SearchSuggestions';
import Page from 'components/Page';
import useSearchParam from 'hooks/useSearchParam';
import globalize from 'lib/globalize';
const COLLECTION_TYPE_PARAM = 'collectionType';
const PARENT_ID_PARAM = 'parentId';
const QUERY_PARAM = 'query';
const Search: FC = () => {
const [searchParams, setSearchParams] = useSearchParams();
const [searchParams] = useSearchParams();
const parentIdQuery = searchParams.get(PARENT_ID_PARAM) || undefined;
const collectionTypeQuery = (searchParams.get(COLLECTION_TYPE_PARAM) || undefined) as CollectionType | undefined;
const urlQuery = searchParams.get(QUERY_PARAM) || '';
const [query, setQuery] = useState(urlQuery);
const prevQuery = usePrevious(query, '');
const [ query, setQuery ] = useSearchParam(QUERY_PARAM);
const [debouncedQuery] = useDebounceValue(query, 500);
useEffect(() => {
if (query !== prevQuery) {
if (query === '' && urlQuery !== '') {
// The query input has been cleared; remove the url param
searchParams.delete(QUERY_PARAM);
setSearchParams(searchParams, { replace: true });
} else if (query !== urlQuery) {
// Update the query url param value
searchParams.set(QUERY_PARAM, query);
setSearchParams(searchParams, { replace: true });
}
} else if (query !== urlQuery) {
// Update the query if the query url param has changed
if (!urlQuery) {
searchParams.delete(QUERY_PARAM);
setSearchParams(searchParams, { replace: true });
}
setQuery(urlQuery);
}
}, [query, prevQuery, searchParams, setSearchParams, urlQuery]);
return (
<Page
id='searchPage'
+41
View File
@@ -0,0 +1,41 @@
import React, { useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import { usePrevious } from './usePrevious';
/**
* A hook for getting and setting a URL search parameter value that automatically handles updates to/from the URL.
* @param param The search parameter name.
*/
const useSearchParam: (param: string) => [ string, React.Dispatch<React.SetStateAction<string>> ] = param => {
const [ searchParams, setSearchParams ] = useSearchParams();
const urlValue = searchParams.get(param) || '';
const [ value, setValue ] = useState(urlValue);
const previousValue = usePrevious(value, '');
useEffect(() => {
if (value !== previousValue) {
if (value === '' && urlValue !== '') {
// The query input has been cleared; remove the url param
searchParams.delete(param);
setSearchParams(searchParams, { replace: true });
} else if (value !== urlValue) {
// Update the query url param value
searchParams.set(param, value);
setSearchParams(searchParams, { replace: true });
}
} else if (value !== urlValue) {
// Update the query if the query url param has changed
if (!urlValue) {
searchParams.delete(param);
setSearchParams(searchParams, { replace: true });
}
setValue(urlValue);
}
}, [ value, previousValue, searchParams, setSearchParams, urlValue ]);
return [ value, setValue ];
};
export default useSearchParam;