NextJS with redux running like as expected but it give warning Text content did not match

I am following example code redux toolkit (counter) with NextJS and trying store state to sessionStorage, it's running as expected but the console give warning
"Warning: Text content did not match. Server: "0" Client: "25"

It is my redux store :

import counterReducer from "./counterSlice";

const initValue = () => {
  let value = 0;
  if (typeof window !== "undefined") {
    if (sessionStorage.getItem("counter")) {
      value = sessionStorage.getItem("counter");
    }
  }
  return parseInt(value);
};

const preloadedState = {
  counter: {
    value: initValue(),
  },
};

export default configureStore({
  reducer: {
    counter: counterReducer,
  },
  preloadedState,
});

and it is my Page Code :


import { useEffect, useState } from "react";

import { useSelector, useDispatch } from "react-redux";

import useSWR from "swr";

import {
  decrement,
  increment,
  incrementByAmount,
  incrementAsync,
  selectCount,
} from "../redux/counterSlice";

export default function Counter() {
  let count = useSelector(selectCount);
  const dispatch = useDispatch();

  return (
    <Layout>
      <div
        style={{ display: "grid", placeContent: "center", textAlign: "center" }}
      >
        <h1>Counter</h1>
        <div style={{ display: "grid", gridAutoFlow: "column", gap: 50 }}>
          <button onClick={() => dispatch(increment())}>Inc</button>
          <h4>{count}</h4>
          <button onClick={() => dispatch(decrement())}>Dec</button>
        </div>
      </div>
    </Layout>
  );
}

Anybody have solution for this problem ?

Upvotes: 0

Views: 669

Answers (1)

Ivan V.
Ivan V.

Reputation: 8081

While you are checking if window object exists ( if not, you are running on the server). The problem is that server rendered value is 0 while the browser rendered value is 25. This is happening because the value is immediately calculated in the browser to be 25 (first render in the browser).

You will need to change your code to defer the calculation until the mounting of the component, so the initial browser value can also be 0 and than use useEffect, which only runs in the browser, to calculate new value.

Upvotes: 5

Related Questions