Skip to content

Commit a5bb7c4

Browse files
authored
router restore should take priority over pending actions (#64449)
Since the router processes events sequentially, we special case `ACTION_NAVIGATE` events to "discard" a pending server action so that it can process the navigation with higher priority. We should apply this same logic to `ACTION_RESTORE` events (e.g. `router.back()`) for the same reason. Fixes #64432 Closes NEXT-3098
1 parent f602b29 commit a5bb7c4

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

packages/next/src/shared/lib/router/action-queue.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,11 @@ function dispatchAction(
155155
action: newAction,
156156
setState,
157157
})
158-
} else if (payload.type === ACTION_NAVIGATE) {
159-
// Navigations take priority over any pending actions.
158+
} else if (
159+
payload.type === ACTION_NAVIGATE ||
160+
payload.type === ACTION_RESTORE
161+
) {
162+
// Navigations (including back/forward) take priority over any pending actions.
160163
// Mark the pending action as discarded (so the state is never applied) and start the navigation action immediately.
161164
actionQueue.pending.discarded = true
162165

test/e2e/app-dir/actions/app-action.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,19 @@ createNextDescribe(
337337
await check(() => browser.url(), `${next.url}/client`, true, 2)
338338
})
339339

340+
it('should not block router.back() while a server action is in flight', async () => {
341+
let browser = await next.browser('/')
342+
343+
// click /client link to add a history entry
344+
await browser.elementByCss("[href='/client']").click()
345+
await browser.elementByCss('#slow-inc').click()
346+
347+
await browser.back()
348+
349+
// intentionally bailing after 2 retries so we don't retry to the point where the async function resolves
350+
await check(() => browser.url(), `${next.url}/`, true, 2)
351+
})
352+
340353
it('should trigger a refresh for a server action that gets discarded due to a navigation', async () => {
341354
let browser = await next.browser('/client')
342355
const initialRandomNumber = await browser

0 commit comments

Comments
 (0)