kirill-konshin / next-redux-wrapper

Redux wrapper for Next.js
MIT License
2.67k stars 266 forks source link

getting an empty state from browser, when I already set a state from server side using getStaticProps. #443

Open zainGohar opened 2 years ago

zainGohar commented 2 years ago

Describe the bug

I am building an application using nextjs and using react-redux along with redux toolkit and next-redux-wrapper.

Now there comes a point in my application where I have to save something in redux store using its state element and that too from getStaticProps. when I do this, it creates a new store with new state and update the value in that store.

Now I am unable to get this value from client/browser side. My browser console as well as the page show empty state.

To Reproduce

I have reproduce it in Code Sand Box:

Code Sand Box Link

Steps to reproduce the behavior:

  1. Go to Index.js in pages folder.
  2. scroll down to getStaticProps, it shows inserting '123' from server side.
  3. Map Dispatch To Props attach props with component where Page component is called. But it shows nothing.

Expected behavior

A clear and concise description of what you expected to happen. How can I set a state from server side so that I can get the desired value from browser side store.

Desktop (please complete the following information):

RaminEgh commented 2 years ago

same issue in version 7.0.5

smo043 commented 2 years ago

Any solution we are also facing the same issue. Migrated to latest version including redux, react-redux. Once the store is hydrated on server, the same store couldn’t be accessible on client with getStaticProps.

Any help with working example using GetStaticProps will be highly appreciated.

smo043 commented 2 years ago

@zainGohar - I fixed the reported issue by following the documentation. Adding my reducer implementation for reference.

Note: diff method is from import {diff} from 'jsondiffpatch'; and below snippet is a part from my root reducer

if (action.type === HYDRATE) {
    // use previous state --- state,
    // apply delta from hydration -- action.payload
    const stateDiff = diff(state, action.payload) as ReduxStateType;
    if (stateDiff) {
        // pick which of the required values to be merged during Server-Client rendering.
       const {data1, data2, data3} = action.payload;
       return deepMerge({}, state, {data1, data2, data3}, {isHydrated: true}) as ReduxStateType;
    }
    return state;
}
jaybe78 commented 2 years ago

@smo043 I added your above piece of code in your sandbox but it's still not working. I must be missing something. Would you be able to look at it ?

 extraReducers: {
    [HYDRATE]: (state, action) => {
      console.log("HYDRATE", action.payload);
      // apply delta from hydration -- action.payload
      const stateDiff = diff(state, action.payload);
      console.log("stateDiff", stateDiff);
      if (stateDiff) {
        console.log(
          deepMerge(state, action.payload, {
            isHydrated: true
          })
        );
        return deepMerge(state, action.payload, {
          isHydrated: true
        });
      }
      return state;
      // return {
      //   ...state,
      //   ...action.payload.transactionData,
      // };
    }
  }
smo043 commented 2 years ago

@jaybe78 - there was a small change, I updated the answer, hope it helps.