From a428a15eb9bee47cb4f1a9e37e2d61c93251dde1 Mon Sep 17 00:00:00 2001 From: Ilia Lesik Date: Wed, 10 Apr 2019 09:39:02 +0300 Subject: [PATCH 1/2] Add useBeforeUnload react hook --- README.md | 1 + docs/useBeforeUnload.md | 16 ++++++++++++++++ src/__stories__/useBeforeUnload.story.tsx | 18 ++++++++++++++++++ src/index.ts | 2 ++ src/useBeforeUnload.ts | 17 +++++++++++++++++ 5 files changed, 54 insertions(+) create mode 100644 docs/useBeforeUnload.md create mode 100644 src/__stories__/useBeforeUnload.story.tsx create mode 100644 src/useBeforeUnload.ts diff --git a/README.md b/README.md index ad663a13..3751eb5b 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ - [`useAsync`](./docs/useAsync.md) — resolves an `async` function. - [`useAsyncFn`](./docs/useAsyncFn.md) — state management for an async function - [`useAsyncRetry`](./docs/useAsyncRetry.md) — `useAsync` with `retry()` method. + - [`useBeforeUnload`](./docs/useBeforeUnload.md) — shows browser alert when user try to reload or close the page. - [`useCopyToClipboard`](./docs/useCopyToClipboard.md) — copies text to clipboard. - [`useDebounce`](./docs/useDebounce.md) — debounces a function. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/side-effects-usedebounce--demo) - [`useFavicon`](./docs/useFavicon.md) — sets favicon of the page. diff --git a/docs/useBeforeUnload.md b/docs/useBeforeUnload.md new file mode 100644 index 00000000..9c4df021 --- /dev/null +++ b/docs/useBeforeUnload.md @@ -0,0 +1,16 @@ +# `useBeforeUnload` + +React side-effect hook that shows browser alert when user try to reload or close the page. + + +## Usage + +```jsx +import {useBeforeUnload} from 'react-use'; + +const Demo = () => { + useBeforeUnload('Are you sure?'); + + return null; +}; +``` diff --git a/src/__stories__/useBeforeUnload.story.tsx b/src/__stories__/useBeforeUnload.story.tsx new file mode 100644 index 00000000..4b0dc31f --- /dev/null +++ b/src/__stories__/useBeforeUnload.story.tsx @@ -0,0 +1,18 @@ +import {storiesOf} from '@storybook/react'; +import * as React from 'react'; +import {useBeforeUnload} from '..'; +import ShowDocs from './util/ShowDocs'; + +const Demo = () => { + useBeforeUnload('Are you sure?'); + + return ( +
+ Try to reload or close tab +
+ ); +}; + +storiesOf('Side effects|useBeforeUnload', module) + .add('Docs', () => ) + .add('Demo', () => ) diff --git a/src/index.ts b/src/index.ts index 271d14eb..1665c3cf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,6 +4,7 @@ import useAsyncFn from './useAsyncFn'; import useAsyncRetry from './useAsyncRetry'; import useAudio from './useAudio'; import useBattery from './useBattery'; +import useBeforeUnload from './useBeforeUnload' import useBoolean from './useBoolean'; import useCopyToClipboard from './useCopyToClipboard'; import useDrop from './useDrop'; @@ -76,6 +77,7 @@ export { useAsyncRetry, useAudio, useBattery, + useBeforeUnload, useBoolean, useCopyToClipboard, useDrop, diff --git a/src/useBeforeUnload.ts b/src/useBeforeUnload.ts new file mode 100644 index 00000000..a244a450 --- /dev/null +++ b/src/useBeforeUnload.ts @@ -0,0 +1,17 @@ +import {useEffect} from "react"; + +const useBeforeUnload = (message?: string) => { + useEffect(() => { + window.onbeforeunload = e => { + e.returnValue = message; + return message; + }; + + return () => { + window.onbeforeunload = null; + return; + } + }, [message]); +}; + +export default useBeforeUnload; \ No newline at end of file From 7653597a3712194b3e91e09f3bfa99e1f8d8b080 Mon Sep 17 00:00:00 2001 From: Ilia Lesik Date: Wed, 10 Apr 2019 21:54:42 +0300 Subject: [PATCH 2/2] Refactor useBeforeUnload with window.addEventListener Remove message param from useBeforeUnload examples. --- docs/useBeforeUnload.md | 2 +- src/__stories__/useBeforeUnload.story.tsx | 2 +- src/useBeforeUnload.ts | 13 ++++++------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/useBeforeUnload.md b/docs/useBeforeUnload.md index 9c4df021..438f0580 100644 --- a/docs/useBeforeUnload.md +++ b/docs/useBeforeUnload.md @@ -9,7 +9,7 @@ React side-effect hook that shows browser alert when user try to reload or close import {useBeforeUnload} from 'react-use'; const Demo = () => { - useBeforeUnload('Are you sure?'); + useBeforeUnload(); return null; }; diff --git a/src/__stories__/useBeforeUnload.story.tsx b/src/__stories__/useBeforeUnload.story.tsx index 4b0dc31f..989ee946 100644 --- a/src/__stories__/useBeforeUnload.story.tsx +++ b/src/__stories__/useBeforeUnload.story.tsx @@ -4,7 +4,7 @@ import {useBeforeUnload} from '..'; import ShowDocs from './util/ShowDocs'; const Demo = () => { - useBeforeUnload('Are you sure?'); + useBeforeUnload(); return (
diff --git a/src/useBeforeUnload.ts b/src/useBeforeUnload.ts index a244a450..26918055 100644 --- a/src/useBeforeUnload.ts +++ b/src/useBeforeUnload.ts @@ -2,15 +2,14 @@ import {useEffect} from "react"; const useBeforeUnload = (message?: string) => { useEffect(() => { - window.onbeforeunload = e => { - e.returnValue = message; - return message; + const beforeUnload = (e) => { + e.preventDefault(); + e.returnValue = message || ""; }; - return () => { - window.onbeforeunload = null; - return; - } + window.addEventListener("beforeunload", beforeUnload); + + return () => window.removeEventListener("beforeunload", beforeUnload); }, [message]); };