Files
hihala-dashboard/src/hooks/useUrlState.ts
fahed 868f46fc6e chore: migrate to TypeScript
- Convert all .js files to .tsx/.ts
- Add types for data structures (MuseumRecord, Metrics, etc.)
- Add type declarations for react-chartjs-2
- Configure tsconfig with relaxed strictness for gradual adoption
- All components now use TypeScript
2026-02-04 13:45:50 +03:00

59 lines
1.6 KiB
TypeScript

import { useEffect, useCallback } from 'react';
import { useSearchParams } from 'react-router-dom';
/**
* Sync state with URL search params
* @param {Object} state - Current state object
* @param {Function} setState - State setter function
* @param {Object} defaultState - Default state values
* @param {Array<string>} keys - Keys to sync with URL
*/
export function useUrlState(state, setState, defaultState, keys) {
const [searchParams, setSearchParams] = useSearchParams();
// Initialize state from URL on mount
useEffect(() => {
const urlState = {};
let hasUrlParams = false;
keys.forEach(key => {
const value = searchParams.get(key);
if (value !== null) {
urlState[key] = value;
hasUrlParams = true;
}
});
if (hasUrlParams) {
setState(prev => ({ ...prev, ...urlState }));
}
}, []); // eslint-disable-line react-hooks/exhaustive-deps
// Update URL when state changes
const updateUrl = useCallback((newState) => {
const params = new URLSearchParams();
keys.forEach(key => {
const value = newState[key];
if (value && value !== defaultState[key]) {
params.set(key, value);
}
});
setSearchParams(params, { replace: true });
}, [keys, defaultState, setSearchParams]);
// Wrap setState to also update URL
const setStateWithUrl = useCallback((updater) => {
setState(prev => {
const newState = typeof updater === 'function' ? updater(prev) : updater;
updateUrl(newState);
return newState;
});
}, [setState, updateUrl]);
return setStateWithUrl;
}
export default useUrlState;