0

The client-side state is not hydrated from the server after creating a new store

CodeSandBox Link - https://codesandbox.io/s/vibrant-aryabhata-l29r2b

Steps to reproduce the behavior:

  1. Run the app on the link above.
  2. Login with any username/password
  3. On login, the token is saved to the cookie, and the page redirects to the dashboard
  4. In the console on the dashboard page, I am printing the current state, which appears okay as we are logged in.
  5. Now refresh the dashboard page.
  6. Server gets token via cookie and is authenticated
  7. But when a new store is created on the client, it doesn't get the hydrated/updated state.
  8. Same can be confirmed from auth state being printed in the console.log of this page.

Expected behavior

On page reload, upon hydration client should also get authenticated, and hence console would print logged in true.

Screenshots

image

You can clearly see in the screenshot above that as per hydration (__NEXT_REDUX_WRAPPER_HYDRATE__ ), the state is updated correctly but on console log on the client-side, I am getting loggedin as false.

  • Next.js: [12]
  • Next-redux-wrapper [7]

Additional context

I am stuck at it for a while and really don't know if there is anything wrong with my code or is a bug. Please look into it and suggest accordingly.

Gaurav
  • 1,668
  • 1
  • 13
  • 30
  • can you post your store and reducer code? – Yilmaz Apr 22 '22 at 23:07
  • @Yilmaz Hi, I've shared entire code on codesandbox - https://codesandbox.io/s/vibrant-aryabhata-l29r2b Go to store folder, there is everything you need – Gaurav Apr 22 '22 at 23:11
  • 1
    I don't know why, but if you return in the reducer a modified state parameter instead of a new object, then it starts working. Seems like there is some code which calls the reducer and then checks that the returned object will have the same reference as an argument. **store/index.js**: `const nextState = Object.assign(state, serverState);` – Artem Fitiskin Apr 27 '22 at 19:03
  • 1
    **Reminder** In this case `Object.assign(a, b)` behaves differently than `{ ...a, ...b }`. It does not create a new object. It modifies the `state` and then share the same link to the `nextState` variable. – Artem Fitiskin Apr 27 '22 at 19:09
  • @ArtemFitiskin while your suggestion works, it triggers a new issue of immutability. https://redux.js.org/style-guide/#do-not-mutate-state – Gaurav Apr 28 '22 at 17:47
  • @Gaurav, yes you don't have to do that. I was just talking about my observation – Artem Fitiskin Apr 29 '22 at 13:27
  • @ArtemFitiskin yeah and that circles me back to the problem, unsolved!! – Gaurav Apr 30 '22 at 10:28

1 Answers1

4

You have a minor misconfiguration. next-redux-wrapper already adds a Provider with the correct store. You need to remove the extra provider you're putting in _app.js. That was the reason why the component wasn't getting the correct data.

  render() {
    const { Component, pageProps, router } = this.props;
    return <Component {...pageProps} router={router} />;
  }
diedu
  • 19,277
  • 4
  • 32
  • 49