import { useCallback, useMemo } from "react"; import { useLocation, useNavigate } from "react-router-dom"; import { usePersistence } from "./use-persistence"; export default function useOverlayState( key: string, defaultValue: S | undefined = undefined, ): [S | undefined, (value: S, replace?: boolean) => void] { const location = useLocation(); const navigate = useNavigate(); const currentLocationState = location.state; const setOverlayStateValue = useCallback( (value: S, replace: boolean = false) => { const newLocationState = { ...currentLocationState }; newLocationState[key] = value; navigate(location.pathname, { state: newLocationState, replace }); }, // we know that these deps are correct // eslint-disable-next-line react-hooks/exhaustive-deps [key, navigate], ); const overlayStateValue = useMemo( () => location.state && location.state[key], [location, key], ); return [overlayStateValue ?? defaultValue, setOverlayStateValue]; } export function usePersistedOverlayState( key: string, defaultValue: S | undefined = undefined, ): [S | undefined, (value: S | undefined, replace?: boolean) => void] { const [persistedValue, setPersistedValue] = usePersistence( key, defaultValue, ); const location = useLocation(); const navigate = useNavigate(); const currentLocationState = location.state; const setOverlayStateValue = useCallback( (value: S | undefined, replace: boolean = false) => { setPersistedValue(value); const newLocationState = { ...currentLocationState }; newLocationState[key] = value; navigate(location.pathname, { state: newLocationState, replace }); }, // we know that these deps are correct // eslint-disable-next-line react-hooks/exhaustive-deps [key, navigate], ); const overlayStateValue = useMemo( () => location.state && location.state[key], [location, key], ); return [ overlayStateValue ?? persistedValue ?? defaultValue, setOverlayStateValue, ]; }