Skip to content

Commit

Permalink
fix: Fix client-side hydration on pages without server-side data fetc…
Browse files Browse the repository at this point in the history
…hing methods

...by dispatching an initial client-side HYDRATE action with state subtrees from cookies (if any)

Closes #22
  • Loading branch information
bjoluc committed Dec 13, 2021
1 parent a9a0ad2 commit 8246f5c
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 19 deletions.
7 changes: 6 additions & 1 deletion main/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ export const wrapMakeStore =
(context: Context) => {
const store = makeStore(context);

if (!isClient()) {
if (isClient()) {
// Dispatch an empty HYDRATE action in case the current page doesn't have getServerSideProps,
// getStaticProps, or getInitialProps and there are state cookies available. The middleware
// will then add any state subtrees from cookies to the HYDRATE action's payload.
store.dispatch({type: HYDRATE, payload: {}});
} else {
if (isAppContext(context)) {
context = context.ctx;
}
Expand Down
23 changes: 5 additions & 18 deletions main/test/index.client.spec.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,19 @@
import {NextPageContext} from "next";
import {HYDRATE} from "next-redux-wrapper";
import {AppContext} from "next/app";
/* eslint-disable-next-line import/no-extraneous-dependencies */ // TSDX includes ts-jest
import {mocked} from "ts-jest/utils";

import {wrapMakeStore} from "../src";
import {NextReduxCookieMiddlewareConfig} from "../src/config";
import {StateCookies} from "../src/cookies";
import {createMiddlewareTestFunctions, makeAppContext, makePageContext, makeStore} from "./util";
import {createMiddlewareTestFunctions, makeStore} from "./util";

jest.mock("../src/cookies");

describe("wrapMakeStore() on the client", () => {
describe("should never dispatch any action, regardless of whether...", () => {
let context: NextPageContext | AppContext;

test("a NextPageContext is provided", () => {
context = makePageContext(false);
});

test("an AppContext is provided", () => {
context = makeAppContext(makePageContext(false));
});

afterEach(() => {
const store = wrapMakeStore(makeStore)(context);
expect(store.dispatch).toHaveBeenCalledTimes(0);
});
it("should dispatch an empty HYDRATE action", () => {
const store = wrapMakeStore(makeStore)({}); // `next-redux-wrapper` always provides an empty context object on the client
expect(store.dispatch).toHaveBeenCalledTimes(1);
expect(store.dispatch).toHaveBeenCalledWith({type: HYDRATE, payload: {}});
});
});

Expand Down

0 comments on commit 8246f5c

Please sign in to comment.