hash-changed.ts 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import { useCallback, useEffect } from 'react';
  2. import { useRouter } from 'next/router';
  3. import { useIsEditable } from '~/stores/context';
  4. import { useEditorMode, determineEditorModeByHash } from '~/stores/ui';
  5. /**
  6. * Change editorMode by browser forward/back operation
  7. */
  8. export const useHashChangedEffect = (): void => {
  9. const router = useRouter();
  10. const { data: isEditable } = useIsEditable();
  11. const { data: editorMode, mutate: mutateEditorMode } = useEditorMode();
  12. const hashchangeHandler = useCallback(() => {
  13. const newEditorMode = determineEditorModeByHash();
  14. if (editorMode !== newEditorMode) {
  15. mutateEditorMode(newEditorMode);
  16. }
  17. }, [editorMode, mutateEditorMode]);
  18. // setup effect
  19. useEffect(() => {
  20. if (!isEditable) {
  21. return;
  22. }
  23. window.addEventListener('hashchange', hashchangeHandler);
  24. // return remove handler
  25. return function cleanup() {
  26. window.removeEventListener('hashchange', hashchangeHandler);
  27. };
  28. }, [hashchangeHandler, isEditable]);
  29. /*
  30. * Route changes by Next Router
  31. * https://nextjs.org/docs/api-reference/next/router
  32. */
  33. useEffect(() => {
  34. router.events.on('routeChangeComplete', hashchangeHandler);
  35. return () => {
  36. router.events.off('routeChangeComplete', hashchangeHandler);
  37. };
  38. }, [hashchangeHandler, router.events]);
  39. };