useLocationQuery.tsx 1.1 KB

12345678910111213141516171819202122232425262728293031323334
  1. import {useMemo} from 'react';
  2. import {decodeInteger, decodeList, decodeScalar} from 'sentry/utils/queryString';
  3. import {useLocation} from 'sentry/utils/useLocation';
  4. type Scalar = string | boolean | number | undefined;
  5. type Decoder = typeof decodeList | typeof decodeScalar | typeof decodeInteger;
  6. export default function useLocationQuery<
  7. Fields extends Record<string, Scalar | Scalar[]>,
  8. >({fields}: {fields: Record<keyof Fields, Fields[string] | Decoder>}): Fields {
  9. const location = useLocation();
  10. const locationFields = {};
  11. const staticFields = {};
  12. Object.entries(fields).forEach(([field, decoderOrValue]) => {
  13. if (typeof decoderOrValue === 'function') {
  14. locationFields[field] = decoderOrValue(location.query[field]);
  15. } else {
  16. staticFields[field] = decoderOrValue;
  17. }
  18. }, {});
  19. const stringyFields = JSON.stringify(locationFields);
  20. const objFields = useMemo(() => JSON.parse(stringyFields), [stringyFields]);
  21. return useMemo(
  22. () => ({
  23. ...objFields,
  24. ...staticFields,
  25. }),
  26. [objFields] // eslint-disable-line react-hooks/exhaustive-deps
  27. );
  28. }