useTraceQueryParamStateSync.tsx 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. import {useEffect, useRef} from 'react';
  2. import * as qs from 'query-string';
  3. import {useNavigate} from 'sentry/utils/useNavigate';
  4. // Syncs query params with URL state. Only performs a state sync if the query params have changed.
  5. export function useTraceQueryParamStateSync(query: Record<string, string | undefined>) {
  6. const previousQueryRef = useRef<Record<string, string | undefined>>(query);
  7. const syncStateTimeoutRef = useRef<number | null>(null);
  8. const navigate = useNavigate();
  9. useEffect(() => {
  10. const keys = Object.keys(query);
  11. const previousKeys = Object.keys(previousQueryRef.current);
  12. if (
  13. keys.length === previousKeys.length &&
  14. keys.every(key => {
  15. return query[key] === previousQueryRef.current[key];
  16. })
  17. ) {
  18. previousQueryRef.current = query;
  19. return;
  20. }
  21. if (syncStateTimeoutRef.current !== null) {
  22. window.clearTimeout(syncStateTimeoutRef.current);
  23. }
  24. previousQueryRef.current = query;
  25. syncStateTimeoutRef.current = window.setTimeout(() => {
  26. navigate(
  27. {
  28. pathname: location.pathname,
  29. query: {
  30. ...qs.parse(location.search),
  31. ...previousQueryRef.current,
  32. },
  33. },
  34. {replace: true}
  35. );
  36. }, 1000);
  37. }, [navigate, query]);
  38. }