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 ////////////////////////////////////////////////////////////////////////////////