next.jsreduxreact-reduxredux-persisthydration

Next.js Redux with redux-persist hydration error


I got Next.js application with Typescript and I'm trying to make redux work with redux-persist, if the state in slice is same as the initial state, the application works fine, but if it actually have to persist some state I get an hydration errors:

Also getting this error on server: Error storing data ReferenceError: window is not defined

Even though the application works as intended even when there are these errors occuring I would like to solve them, so it doesn't look this messy, but I'm pretty lost on why this is happening.

Here is my trimmed code for redux set up:

slice.ts

import { InquiryCartState } from "@/types/InquiryCart";
import { createSlice } from "@reduxjs/toolkit";

const initialState: InquiryCartState = {
  products: []
};

const inquiryCartSlice = createSlice({
  name: "inquiryCart",
  initialState,
  reducers: {
  },
});

export default inquiryCartSlice.reducer;

rootReducer.ts

import { combineReducers } from "@reduxjs/toolkit";
import inquiryCartReducer from "./slice";
import AsyncStorage from '@react-native-async-storage/async-storage';
import { persistReducer } from "redux-persist";

const persistConfig = {
  key: "root",
  storage: AsyncStorage,
};

export const rootReducer = combineReducers({
  inquiryCart: persistReducer(persistConfig, inquiryCartReducer),
})

store.ts

import { configureStore } from "@reduxjs/toolkit";
import { rootReducer } from "./rootReducer";

export const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({ serializableCheck: false })
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

ReduxProvider.ts

"use client"

import { Provider } from "react-redux";
import { ReactNode } from "react";
import { store } from "@/lib/store";
import { persistStore } from "redux-persist";

persistStore(store)
export default function ReduxProvider({ children }: { children: ReactNode }) {
  return <Provider store={store}>{children}</Provider>;
}

Solution

  • The server has no access to your persisted data, so SSR will render whatever would be rendered for a newly created Redux store, while your Client will render depending on the persisted data.

    There is no way of telling the server what your user has persisted, so the best you can do is either live with this or disable persistance.