From fcc30188056aa0ecbcba526f80bce6d51e687193 Mon Sep 17 00:00:00 2001 From: Sungjin Kim Date: Fri, 20 Jan 2023 03:51:40 +0900 Subject: [PATCH 1/3] fix: replace beforeunload to pagehide for safafi on ios (#9522) --- .changeset/small-squids-wash.md | 5 +++++ contributors.yml | 1 + 2 files changed, 6 insertions(+) create mode 100644 .changeset/small-squids-wash.md diff --git a/.changeset/small-squids-wash.md b/.changeset/small-squids-wash.md new file mode 100644 index 0000000000..b7570a0122 --- /dev/null +++ b/.changeset/small-squids-wash.md @@ -0,0 +1,5 @@ +--- +"react-router-dom": patch +--- + +Modified to use pagehide instead of beforeunload to work in the environment of safari on ios diff --git a/contributors.yml b/contributors.yml index c9fdcf2f39..627ff510ad 100644 --- a/contributors.yml +++ b/contributors.yml @@ -166,3 +166,4 @@ - xavier-lc - xcsnowcity - yuleicul +- jakkku From 6dec3920c9b5100c79b71f76ec78c9a77d868576 Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Thu, 19 Jan 2023 14:02:08 -0500 Subject: [PATCH 2/3] Add internal usePageHide and change useScrollRestoration --- packages/react-router-dom/index.tsx | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/packages/react-router-dom/index.tsx b/packages/react-router-dom/index.tsx index ff43c18918..27c7741f7f 100644 --- a/packages/react-router-dom/index.tsx +++ b/packages/react-router-dom/index.tsx @@ -1143,8 +1143,8 @@ function useScrollRestoration({ }; }, []); - // Save positions on unload - useBeforeUnload( + // Save positions on pagehide + usePageHide( React.useCallback(() => { if (navigation.state === "idle") { let key = (getKey ? getKey(location, matches) : null) || location.key; @@ -1241,6 +1241,28 @@ export function useBeforeUnload( }, [callback, capture]); } +/** + * Setup a callback to be fired on the window's `pagehide` event. This is + * useful for saving some data to `window.localStorage` just before the page + * refreshes. This event is better supported than beforeunload across browsers. + * + * Note: The `callback` argument should be a function created with + * `React.useCallback()`. + */ +function usePageHide( + callback: (event: PageTransitionEvent) => any, + options?: { capture?: boolean } +): void { + let { capture } = options || {}; + React.useEffect(() => { + let opts = capture != null ? { capture } : undefined; + window.addEventListener("pagehide", callback, opts); + return () => { + window.removeEventListener("pagehide", callback, opts); + }; + }, [callback, capture]); +} + /** * Wrapper around useBlocker to show a window.confirm prompt to users instead * of building a custom UI with useBlocker. From 67dd17f7acc6f3aa590c3d915f61c008807427e3 Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Thu, 19 Jan 2023 14:56:26 -0500 Subject: [PATCH 3/3] Update changeset --- .changeset/small-squids-wash.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/small-squids-wash.md b/.changeset/small-squids-wash.md index b7570a0122..8530430d1f 100644 --- a/.changeset/small-squids-wash.md +++ b/.changeset/small-squids-wash.md @@ -2,4 +2,4 @@ "react-router-dom": patch --- -Modified to use pagehide instead of beforeunload to work in the environment of safari on ios +Use `pagehide` instead of `beforeunload` for ``. This has better cross-browser support, specifically on Mobile Safari.