useCleanQueryParamsOnRouteLeave.tsx 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import {useCallback, useEffect} from 'react';
  2. import {browserHistory} from 'react-router';
  3. import type {Location} from 'history';
  4. import {useLocation} from 'sentry/utils/useLocation';
  5. type Opts = {
  6. fieldsToClean: string[];
  7. };
  8. export function handleRouteLeave<Q extends object>({
  9. fieldsToClean,
  10. newLocation,
  11. oldPathname,
  12. }: {
  13. fieldsToClean: string[];
  14. newLocation: Location<Q>;
  15. oldPathname: string;
  16. }) {
  17. const hasSomeValues = fieldsToClean.some(
  18. field => newLocation.query[field] !== undefined
  19. );
  20. if (newLocation.pathname === oldPathname || !hasSomeValues) {
  21. return;
  22. }
  23. // Removes fields from the URL on route leave so that the parameters will
  24. // not interfere with other pages
  25. const query = fieldsToClean.reduce(
  26. (newQuery, field) => {
  27. newQuery[field] = undefined;
  28. return newQuery;
  29. },
  30. {...newLocation.query}
  31. );
  32. browserHistory.replace({
  33. pathname: newLocation.pathname,
  34. query,
  35. });
  36. }
  37. function useCleanQueryParamsOnRouteLeave({fieldsToClean}: Opts) {
  38. const location = useLocation();
  39. const onRouteLeave = useCallback(
  40. newLocation => {
  41. handleRouteLeave({
  42. fieldsToClean,
  43. newLocation,
  44. oldPathname: location.pathname,
  45. });
  46. },
  47. [location.pathname, fieldsToClean]
  48. );
  49. useEffect(() => {
  50. return browserHistory.listen(onRouteLeave);
  51. }, [onRouteLeave]);
  52. }
  53. export default useCleanQueryParamsOnRouteLeave;