Skip to content

Commit 2930c7c

Browse files
samorianArian Schneberger
andauthored
Added nextLocation to return value. (#188)
Co-authored-by: Arian Schneberger <[email protected]>
1 parent a4a98d6 commit 2930c7c

File tree

4 files changed

+27
-9
lines changed

4 files changed

+27
-9
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,16 @@ yarn add react-router-prompt
5656
}) => boolean
5757
```
5858
59-
2. `beforeConfirm()` : `Promise<unknown>` _(Optional)_
59+
2. `beforeConfirm(nextLocation?: Location)` : `Promise<unknown>` _(Optional)_
6060
6161
3. `beforeCancel()` : `Promise<unknown>` _(Optional)_
6262
6363
### Return values
6464
6565
1. `isActive`: `Boolean`
66-
2. `onConfirm()`: `void`
66+
2. `onConfirm(nextLocation?: Location)`: `void`
6767
3. `onCancel()`: `void`
68+
4. `nextLocation`: `Location | undefined`
6869
6970
#### Note 🗒️
7071

src/hooks/use-confirm.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
1-
import { BlockerFunction } from "react-router-dom"
1+
import { BlockerFunction, Location } from "react-router-dom"
22
import usePrompt from "./use-prompt"
3+
import { useState } from "react"
34

45
declare interface InitialStateType {
56
isActive: boolean
67
onConfirm(): void
78
resetConfirmation(): void
9+
nextLocation?: Location
810
}
911

1012
const useConfirm = (when: boolean | BlockerFunction): InitialStateType => {
11-
const blocker = usePrompt(when)
13+
const [nextLocation, setNextLocation] = useState<Location | null>(null)
14+
15+
const blocker = usePrompt(when, (location) => {
16+
setNextLocation(location)
17+
})
1218

1319
const resetConfirmation = () => {
1420
if (blocker.state === "blocked") blocker.reset()
@@ -22,6 +28,7 @@ const useConfirm = (when: boolean | BlockerFunction): InitialStateType => {
2228
isActive: blocker.state === "blocked",
2329
onConfirm,
2430
resetConfirmation,
31+
nextLocation: nextLocation || undefined,
2532
}
2633
}
2734

src/hooks/use-prompt.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
useBlocker,
55
Blocker,
66
BlockerFunction,
7+
Location,
78
} from "react-router-dom"
89

910
// You can abstract `useBlocker` to use the browser's `window.confirm` dialog to
@@ -17,13 +18,19 @@ import {
1718
// or the app may stay on the correct page but the browser's history stack gets
1819
// out of whack. You should test your own implementation thoroughly to make sure
1920
// the tradeoffs are right for your users.
20-
function usePrompt(when: boolean | BlockerFunction): Blocker {
21+
function usePrompt(
22+
when: boolean | BlockerFunction,
23+
onNavigate?: (nextLocation: Location) => void,
24+
): Blocker {
2125
const blocker = useBlocker(when)
2226
useEffect(() => {
27+
if (blocker.state === "blocked" && blocker.location && onNavigate) {
28+
onNavigate(blocker.location)
29+
}
2330
if (blocker.state === "blocked" && !when) {
2431
blocker.reset()
2532
}
26-
}, [blocker, when])
33+
}, [blocker, when, onNavigate])
2734

2835
useBeforeUnload(
2936
useCallback(

src/index.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useCallback } from "react"
2-
import { BlockerFunction } from "react-router-dom"
2+
import { BlockerFunction, Location } from "react-router-dom"
33

44
import useConfirm from "./hooks/use-confirm"
55
import usePrompt from "./hooks/use-prompt"
@@ -10,9 +10,10 @@ type ReactRouterPromptProps = {
1010
isActive: boolean
1111
onCancel: () => void
1212
onConfirm: () => void
13+
nextLocation?: Location
1314
}) => React.ReactNode
1415
beforeCancel?: () => Promise<unknown>
15-
beforeConfirm?: () => Promise<unknown>
16+
beforeConfirm?: (nextLocation?: Location) => Promise<unknown>
1617
}
1718

1819
/**
@@ -39,7 +40,8 @@ function ReactRouterPrompt({
3940
beforeCancel,
4041
beforeConfirm,
4142
}: ReactRouterPromptProps) {
42-
const { isActive, onConfirm, resetConfirmation } = useConfirm(when)
43+
const { isActive, onConfirm, resetConfirmation, nextLocation } =
44+
useConfirm(when)
4345

4446
const onConfirmAction = useCallback(async () => {
4547
if (beforeConfirm) await beforeConfirm()
@@ -58,6 +60,7 @@ function ReactRouterPrompt({
5860
isActive: true,
5961
onConfirm: onConfirmAction,
6062
onCancel: onResetAction,
63+
nextLocation: nextLocation || undefined,
6164
})}
6265
</>
6366
)

0 commit comments

Comments
 (0)