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..438f0580 --- /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(); + + return null; +}; +``` diff --git a/src/__stories__/useBeforeUnload.story.tsx b/src/__stories__/useBeforeUnload.story.tsx new file mode 100644 index 00000000..989ee946 --- /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(); + + 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..26918055 --- /dev/null +++ b/src/useBeforeUnload.ts @@ -0,0 +1,16 @@ +import {useEffect} from "react"; + +const useBeforeUnload = (message?: string) => { + useEffect(() => { + const beforeUnload = (e) => { + e.preventDefault(); + e.returnValue = message || ""; + }; + + window.addEventListener("beforeunload", beforeUnload); + + return () => window.removeEventListener("beforeunload", beforeUnload); + }, [message]); +}; + +export default useBeforeUnload; \ No newline at end of file