UnsavedAlertDialog.tsx 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. import React, { useCallback, useEffect, memo } from 'react';
  2. import { useTranslation } from 'next-i18next';
  3. import { useRouter } from 'next/router';
  4. import { useIsEnabledUnsavedWarning } from '~/stores/editor';
  5. const UnsavedAlertDialog = (): JSX.Element => {
  6. const { t } = useTranslation();
  7. const router = useRouter();
  8. const { data: isEnabledUnsavedWarning } = useIsEnabledUnsavedWarning();
  9. const alertUnsavedWarningByBrowser = useCallback((e) => {
  10. if (isEnabledUnsavedWarning) {
  11. e.preventDefault();
  12. // returnValue should be set to show alert dialog
  13. // default alert message cannot be changed.
  14. // See -> https://developer.mozilla.org/ja/docs/Web/API/Window/beforeunload_event
  15. e.returnValue = '';
  16. return;
  17. }
  18. }, [isEnabledUnsavedWarning]);
  19. const alertUnsavedWarningByNextRouter = useCallback(() => {
  20. if (isEnabledUnsavedWarning) {
  21. // eslint-disable-next-line no-alert
  22. window.alert(t('page_edit.changes_not_saved'));
  23. }
  24. return;
  25. }, [isEnabledUnsavedWarning, t]);
  26. /*
  27. * Route changes by Browser
  28. * Example: window.location.href, F5
  29. */
  30. useEffect(() => {
  31. window.addEventListener('beforeunload', alertUnsavedWarningByBrowser);
  32. return () => {
  33. window.removeEventListener('beforeunload', alertUnsavedWarningByBrowser);
  34. };
  35. }, [alertUnsavedWarningByBrowser]);
  36. /*
  37. * Route changes by Next Router
  38. * https://nextjs.org/docs/api-reference/next/router
  39. */
  40. useEffect(() => {
  41. router.events.on('routeChangeStart', alertUnsavedWarningByNextRouter);
  42. return () => {
  43. router.events.off('routeChangeStart', alertUnsavedWarningByNextRouter);
  44. };
  45. }, [alertUnsavedWarningByNextRouter, router.events]);
  46. return <></>;
  47. };
  48. export default memo(UnsavedAlertDialog);