Skip to content

Commit 0529002

Browse files
authored
Add unstable_usePrompt (#9932)
1 parent 4326424 commit 0529002

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

.changeset/spicy-nails-compete.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"react-router-dom": patch
3+
---
4+
5+
Add `unstable_usePrompt`

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,10 @@
118118
"none": "15 kB"
119119
},
120120
"packages/react-router-dom/dist/react-router-dom.production.min.js": {
121-
"none": "11 kB"
121+
"none": "11.5 kB"
122122
},
123123
"packages/react-router-dom/dist/umd/react-router-dom.production.min.js": {
124-
"none": "16.5 kB"
124+
"none": "17 kB"
125125
}
126126
}
127127
}

packages/react-router-dom/index.tsx

+33
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
useNavigate,
1919
useNavigation,
2020
useResolvedPath,
21+
unstable_useBlocker as useBlocker,
2122
UNSAFE_DataRouterContext as DataRouterContext,
2223
UNSAFE_DataRouterStateContext as DataRouterStateContext,
2324
UNSAFE_NavigationContext as NavigationContext,
@@ -1210,6 +1211,38 @@ export function useBeforeUnload(
12101211
};
12111212
}, [callback, capture]);
12121213
}
1214+
1215+
/**
1216+
* Wrapper around useBlocker to show a window.confirm prompt to users instead
1217+
* of building a custom UI with useBlocker.
1218+
*
1219+
* Warning: This has *a lot of rough edges* and behaves very differently (and
1220+
* very incorrectly in some cases) across browsers if user click addition
1221+
* back/forward navigations while the confirm is open. Use at your own risk.
1222+
*/
1223+
function usePrompt({ when, message }: { when: boolean; message: string }) {
1224+
let blocker = useBlocker(when);
1225+
1226+
React.useEffect(() => {
1227+
if (blocker.state === "blocked" && !when) {
1228+
blocker.reset();
1229+
}
1230+
}, [blocker, when]);
1231+
1232+
React.useEffect(() => {
1233+
if (blocker.state === "blocked") {
1234+
let proceed = window.confirm(message);
1235+
if (proceed) {
1236+
setTimeout(blocker.proceed, 0);
1237+
} else {
1238+
blocker.reset();
1239+
}
1240+
}
1241+
}, [blocker, message]);
1242+
}
1243+
1244+
export { usePrompt as unstable_usePrompt };
1245+
12131246
//#endregion
12141247

12151248
////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)