Skip to content

Commit 2cbf43c

Browse files
Handle shallow navigation edge case
1 parent a7def09 commit 2cbf43c

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

src/get-scope.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,32 @@ describe("getClientScope", () => {
8888
expect(clientScopeOne.getState(longUpFx.inFlight)).toEqual(0);
8989
expect(clientScopeOne.getState($specialData)).toEqual(getFixedDate());
9090
});
91+
test("shallow navigation to same page", async () => {
92+
const serverScope = fork();
93+
94+
await allSettled(up, { scope: serverScope });
95+
await allSettled(up, { scope: serverScope });
96+
await allSettled(up, { scope: serverScope });
97+
98+
const values = serialize(serverScope);
99+
100+
const clientScopeOne = getClientScope(values);
101+
102+
expect(clientScopeOne.getState($count)).toEqual(3);
103+
104+
await allSettled(up, { scope: clientScopeOne });
105+
106+
expect(clientScopeOne.getState($count)).toEqual(4);
107+
108+
// This imitates shallow navigation to same page, e.g. with different query params
109+
//
110+
// Next.js will reuse the same pageProps instance in this case
111+
// which will basically override current page state with initial one
112+
//
113+
// So we need to basically just ignore it, because
114+
// we already have the latest state in the client scope
115+
const clientScopeTwo = getClientScope(values);
116+
117+
expect(clientScopeTwo.getState($count)).toEqual(4);
118+
});
91119
});

src/get-scope.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,31 @@ function getServerScope(values?: Values) {
1616
* This temporary solution on hacks allows us to solve the pain of library users when working with Next.js, as well as gather much more information to develop a better API.
1717
*/
1818
const _currentScope: Scope = fork();
19+
let prevValues: Values;
1920
/**
2021
* @private
2122
*
2223
* exported for tests only
2324
*/
2425
export function getClientScope(values?: Values) {
25-
if (!values) return _currentScope;
26+
if (
27+
!values ||
28+
/**
29+
* This is a hack to handle edge cases with shallow navigation
30+
*
31+
* In this case Next.js will basically re-use old pageProps,
32+
* but we already have latest state in the client scope
33+
*
34+
* So this update is just skipped
35+
*/
36+
values === prevValues
37+
)
38+
return _currentScope;
39+
40+
/**
41+
* Saving previous values to handle edge cases with shallow navigation
42+
*/
43+
prevValues = values;
2644

2745
HACK_injectValues(_currentScope, values);
2846
HACK_updateScopeRefs(_currentScope, values);

0 commit comments

Comments
 (0)