vikejs / vike

🔨 Flexible, lean, community-driven, dependable, fast Vite-based frontend framework.
https://vike.dev
MIT License
4.3k stars 348 forks source link

What's the proper way of updating redux store after fetching data ? #331

Closed jaybe78 closed 2 years ago

jaybe78 commented 2 years ago

Hi,

I have a boilerplate there that comes up with vps/webpack5/redux

My goal is to fetch data from onBeforeRender, then dispatch the result to update the store, so that It can be rendered in the render function.

Let's look at _default.page.server.jsx, where I fetch some data and then dispatch the result to update the state.

async function onBeforeRender(pageContext) {
  const store = getStore(pageContext.PRELOADED_STATE);
  const list = await fetch('https://xeno-canto.org/api/2/recordings?query=cnt:brazil')
  const result = await list.json()

  store.dispatch({ type: 'update_count', payload: result.numPages })

  // Grab the initial state from our Redux store
  const PRELOADED_STATE = store.getState()
  console.log(PRELOADED_STATE)
  return {
    pageContext: {
      PRELOADED_STATE,
      store, // pass store otherwise render function will use older version of store
    },
  }
}

What I've noticed is that, after dispatching the action in onBeforeRender, then, in the render function, store.getState() is unchanged... I then end up with a mismatch.

So the only "solution" I have found is to return the updated store from onBeforeRender, to render the html with the updated store:

async function render(pageContext) {
  const { Page, pageProps } = pageContext;
  const stream = await renderToStream(
      <Provider store={pageContext.store}>
    <PageLayout>
      <Page {...pageProps} />
    </PageLayout></Provider>,
    {
      disable: false,
      webStream: false,
    }
  );

I would like to know whether that's how supposed to be done or if my implementation is not right ?

Thanks

brillout commented 2 years ago

Yes, see examples/redux/.