useNavigate.tsx 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. import {useCallback, useEffect, useRef} from 'react';
  2. import {useRouteContext} from 'sentry/utils/useRouteContext';
  3. import {normalizeUrl} from 'sentry/utils/withDomainRequired';
  4. type NavigateOptions = {
  5. replace?: boolean;
  6. state?: any;
  7. };
  8. export function useNavigate() {
  9. const route = useRouteContext();
  10. const navigator = route.router;
  11. const hasMountedRef = useRef(false);
  12. useEffect(() => {
  13. hasMountedRef.current = true;
  14. });
  15. const navigate = useCallback(
  16. (to: string | number, options: NavigateOptions = {}) => {
  17. if (!hasMountedRef.current) {
  18. throw new Error(
  19. `You should call navigate() in a React.useEffect(), not when your component is first rendered.`
  20. );
  21. }
  22. if (typeof to === 'number') {
  23. return navigator.go(to);
  24. }
  25. const nextState = {
  26. pathname: normalizeUrl(to),
  27. state: options.state,
  28. };
  29. if (options.replace) {
  30. return navigator.replace(nextState);
  31. }
  32. return navigator.push(nextState);
  33. },
  34. [navigator]
  35. );
  36. return navigate;
  37. }