Skip to content

Commit 76074cf

Browse files
authored
fix: useBlocker does not work with memoryHistory (#6406)
1 parent 7a140d9 commit 76074cf

2 files changed

Lines changed: 63 additions & 1 deletion

File tree

packages/history/src/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,11 @@ export function createMemoryHistory(
593593

594594
const getLocation = () => parseHref(entries[index]!, states[index])
595595

596+
let blockers: Array<NavigationBlocker> = []
597+
const _getBlockers = () => blockers
598+
const _setBlockers = (newBlockers: Array<NavigationBlocker>) =>
599+
(blockers = newBlockers)
600+
596601
return createHistory({
597602
getLocation,
598603
getLength: () => entries.length,
@@ -620,6 +625,8 @@ export function createMemoryHistory(
620625
index = Math.min(Math.max(index + n, 0), entries.length - 1)
621626
},
622627
createHref: (path) => path,
628+
getBlockers: _getBlockers,
629+
setBlockers: _setBlockers,
623630
})
624631
}
625632

packages/history/tests/createMemoryHistory.test.ts

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, expect, test } from 'vitest'
1+
import { describe, expect, test, vi } from 'vitest'
22
import { createMemoryHistory } from '../src'
33

44
describe('createMemoryHistory', () => {
@@ -76,4 +76,59 @@ describe('createMemoryHistory', () => {
7676
history.push('/c', { i: 3 })
7777
expect((history.location.state as any).i).toBe(3)
7878
})
79+
80+
test('block prevents navigation', async () => {
81+
const history = createMemoryHistory({ initialEntries: ['/'] })
82+
const blockerFn = vi.fn(() => true) // Always block
83+
84+
const unblock = history.block({
85+
blockerFn,
86+
enableBeforeUnload: false,
87+
})
88+
89+
await history.push('/a')
90+
91+
// Navigation should be blocked
92+
expect(history.location.pathname).toBe('/')
93+
expect(blockerFn).toHaveBeenCalled()
94+
95+
unblock()
96+
})
97+
98+
test('block allows navigation when blockerFn returns false', async () => {
99+
const history = createMemoryHistory({ initialEntries: ['/'] })
100+
const blockerFn = vi.fn(() => false) // Never block
101+
102+
const unblock = history.block({
103+
blockerFn,
104+
enableBeforeUnload: false,
105+
})
106+
107+
await history.push('/a')
108+
109+
// Navigation should proceed
110+
expect(history.location.pathname).toBe('/a')
111+
expect(blockerFn).toHaveBeenCalled()
112+
113+
unblock()
114+
})
115+
116+
test('unblock removes blocker', async () => {
117+
const history = createMemoryHistory({ initialEntries: ['/'] })
118+
const blockerFn = vi.fn(() => true) // Always block
119+
120+
const unblock = history.block({
121+
blockerFn,
122+
enableBeforeUnload: false,
123+
})
124+
125+
// Unblock immediately
126+
unblock()
127+
128+
await history.push('/a')
129+
130+
// Navigation should proceed since blocker was removed
131+
expect(history.location.pathname).toBe('/a')
132+
expect(blockerFn).not.toHaveBeenCalled()
133+
})
79134
})

0 commit comments

Comments
 (0)