From a5e45d70b8cd27e29869b684f350b83501d7d156 Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Mon, 12 Dec 2022 18:13:37 -0500 Subject: [PATCH] Export useBeforeUnload --- docs/hooks/use-before-unload.md | 32 +++++++++++++++++++++++++++++ packages/react-router-dom/index.tsx | 13 ++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 docs/hooks/use-before-unload.md diff --git a/docs/hooks/use-before-unload.md b/docs/hooks/use-before-unload.md new file mode 100644 index 0000000000..613284afbe --- /dev/null +++ b/docs/hooks/use-before-unload.md @@ -0,0 +1,32 @@ +--- +title: useBeforeUnload +new: true +--- + +# `useBeforeUnload` + +This hook is just a helper around `window.onbeforeunload`. It can be useful to save important application state on the page (to something like the browser's local storage), before the user navigates away from your page. That way if they come back you can restore any stateful information (restore form input values, etc.) + +```tsx lines=[1,7-11] +import { useBeforeUnload } from "react-router-dom"; + +function SomeForm() { + const [state, setState] = React.useState(null); + + // save it off before users navigate away + useBeforeUnload( + React.useCallback(() => { + localStorage.stuff = state; + }, [state]) + ); + + // read it in when they return + React.useEffect(() => { + if (state === null && localStorage.stuff != null) { + setState(localStorage.stuff); + } + }, [state]); + + return <>{/*... */}; +} +``` diff --git a/packages/react-router-dom/index.tsx b/packages/react-router-dom/index.tsx index 2aafcd7421..8cfd873b7f 100644 --- a/packages/react-router-dom/index.tsx +++ b/packages/react-router-dom/index.tsx @@ -1179,7 +1179,17 @@ function useScrollRestoration({ }, [location, restoreScrollPosition, preventScrollReset, skip]); } -function useBeforeUnload(callback: () => any): void { +/** + * Setup a callback to be fired on the window's `beforeunload` event. This is + * useful for saving some data to `window.localStorage` just before the page + * refreshes. + * + * Note: The `callback` argument should be a function created with + * `React.useCallback()`. + */ +export function useBeforeUnload( + callback: (event: BeforeUnloadEvent) => any +): void { React.useEffect(() => { window.addEventListener("beforeunload", callback); return () => { @@ -1187,7 +1197,6 @@ function useBeforeUnload(callback: () => any): void { }; }, [callback]); } - //#endregion ////////////////////////////////////////////////////////////////////////////////