kirill-konshin / next-redux-wrapper

Redux wrapper for Next.js

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Hydrate action isn't called with wrapper.getStaticProps on first render

ebrine opened this issue · comments

Describe the bug

I am using getStaticProps on a page to fetch data, dispatch a redux action to set the state, and later get that state from redux to render data to the page. I am using HYDRATE to sync the server state with the client state. It works fine if I start on a home page, and then navigate to the page that uses getStaticProps. Eg HYDRATE is called, client state is updated, the page renders correctly with the redux data. However, if I just load that page route on its own, without loading any other page first, HYDRATE isn't called, redux state doesn't get synced to the client, and the page does not render correctly because it does not have the data in redux.

To Reproduce

I don't have a sandbox to use.

Here is some code:

  wrapper.getStaticProps(store => async ({ params }) => {
    const id = params?.id;
    const headers = new Headers();

    // omitting actual headers here, not necessary for this demo
    const requestOptions: RequestInit = {
      method: 'GET',
      headers: headers,
      redirect: 'follow',
    };

    let data: any | null = null;

    await fetch(`my_url_with_param_${id}`, requestOptions)
      .then(response => response.text())
      .then(result => {
        data = JSON.parse(result).media;
      })
      .catch(error => console.log('error', error));

    const entry = {
      [data._id]: { id: data._id, src: data.url },
    };
    store.dispatch(setSelectedEntry({ selectedEntry: entry }));

    return {
      props: {
        selectedEntry,
        // NOTE - at this point,
        // I am not actually using this `selectedEntry` prop in my Page Component,
        // I am instead using const selectedEntry = useAppSelector(state => state.stage.selectedEntry);
        // I believe at this point, I shouldn't have to pass any props back from getStaticProps for my situation
      },
    };
  });

Relevant slice of state:

export const dataSlice = createSlice({
  name: 'data',
  initialState,
  reducers: { ...dataReducers },
  extraReducers: {
    [HYDRATE]: (state, action) => {
      state.selectedEntry = action.payload.data.selectedEntry;
    },
  },
});

Expected behavior

When I fresh load a page that uses getStaticProps to dispatch a redux action, I expect that server state to get hydrated to the client redux state.

Screenshots

N/A

Desktop (please complete the following information):

  • OS: macOS Ventura Version 13.2.1
  • Chrome Version 112.0.5615.49 (Official Build) (arm64)
  • Version ^8.1.0

Additional context

If I use getServerSideProps to do the same thing as above, I get the expected behavior (HYDRATE happens correctly, client side redux state updates correctly, page renders correctly with new redux state). However, I do not want to use getServerSideProps for my use case.

What I think is crucial context -- I dropped my next-redux-wrapper version down to 7.0.5 and I am not experiencing my bug. I looked in the source code, and I think the issue has to do with changes to hydrateOrchestrator / useHybridHydrate in src/index, in particular the portion of useHybridHydrate where hydrate is not called before a page navigation has occurred. Here is the comment:
// We should only hydrate when the router has changed routes

I'm not sure if that change just didn't take into consideration this particular case that I am encountering, or if my use case is intended not to work, or if I'm possibly making another error. Like I mentioned above, what I'm trying to do works correctly if I switch to getServerSideProps, as well as if I go to a different next-redux-wrapper version.

I would love to hear from the developers whether they think this is a true bug. Hopefully I gave enough information to be helpful.

I just wanted to add that I am experiencing the exact same issue as described above, after updating my version of next-redux-wrapepr.

i have the same problem, if you find any solution please let me know