(hook) 객체를 URL queryparam으로 변경하는 hook
12/9/2024
'use client';
import { useEffect, useState, useMemo } from 'react';
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
type UseCustomSearchParamsProps = object;
const useCustomSearchParams = <T extends Record<string, any>>(defaultParams: UseCustomSearchParamsProps) => {
const router = useRouter();
const pathname = usePathname();
const _searchParams = useSearchParams();
// Parse URL search params
const urlSearchParams = useMemo(() => {
const params = new URLSearchParams(_searchParams.toString());
return Object.fromEntries(params.entries()) as T;
}, [_searchParams]);
// Initialize local search params
const [localSearchParams, setLocalSearchParams] = useState<T>(() => {
const params = new URLSearchParams(_searchParams.toString());
for (const [key, value] of Object.entries(defaultParams)) {
if (!params.has(key)) {
params.set(key, String(value));
}
}
return Object.fromEntries(params.entries()) as T;
});
useEffect(() => {
update();
}, []);
const [shouldUpdate, setShouldUpdate] = useState(false);
const setSearchParams = (newParams: Partial<T>, isUpdate: boolean = false): void => {
setLocalSearchParams((prev) => ({
...prev,
...newParams,
}));
if (isUpdate) {
setShouldUpdate(true);
}
};
useEffect(() => {
if (shouldUpdate) {
update();
setShouldUpdate(false);
}
}, [localSearchParams, shouldUpdate]);
// Update the URL
const update = () => {
const params = new URLSearchParams();
for (const [key, value] of Object.entries(localSearchParams)) {
if (value !== undefined) {
params.set(key, String(value));
} else {
params.delete(key);
}
}
router.replace(`${pathname}?${params.toString()}`, { scroll: false });
};
// Check if localSearchParams differ from urlSearchParams
const isChanged = useMemo(() => {
return JSON.stringify(localSearchParams) !== JSON.stringify(urlSearchParams);
}, [localSearchParams, urlSearchParams]);
return {
searchParams: localSearchParams,
urlSearchParams,
setSearchParams,
update,
isChanged,
};
};
export default useCustomSearchParams;