Easy-peasy: Issue with Next.js SSR (dispatching actions in getinitialprops) and persisting state

Created on 5 Dec 2019  路  7Comments  路  Source: ctrlplusb/easy-peasy

Hi folks, thanks for the great work on the library !! :)

I am having some trouble when dispatching an action in getInitialProps with my store model defined with persist(store). The store seems to ignore the actions dispatched in getInitialProps and keep the old state. These actions include thunks (async calls).

I defined my model like this:
const model = persist( { data, user, UI })

getInitialProps, which works fine without persist, does something like this:

Resources.getInitialProps = async function(context) {    
try {
    const resource = context.query.resource
    const store = context.reduxStore
    await store.dispatch.data.fetchResources(resource)
    const storeResources = await store.getState().data
    let podcasts= storeResources.podcasts
    return{
        podcasts,
    }
    } catch (error) {
        console.log (error)
        return{
            podcasts,
        }
    }
}

The actions dispatched in getInitialProps actually happen, as the variable podcasts is the expected one. They seem to be whipped out though.

My _app.js is:
``` class MyApp extends App {
static async getInitialProps({ Component, ctx }) {

const { reduxStore } = ctx

const isClient = typeof window !== 'undefined'
  if (isClient){
  const token = Cookie.get('FBIdToken')
  if (token) {
    const decodedToken = jwtDecode(token)
    console.log(decodedToken)
    if (decodedToken.exp * 1000 < Date.now()) {
      reduxStore.dispatch.user.logoutUser()
      console.log ('token expired! Log out')
    }
    else {
      reduxStore.dispatch.user.setAuthenticated()
    }
  }
}


const pageProps = Component.getInitialProps
  ? await Component.getInitialProps(ctx)
  : {}

return { pageProps }

}
render() {
const { Component, pageProps, reduxStore } = this.props
return (


)
}
}

export default withReduxStore(MyApp)
```
Could anyone give me some guidance??
Thanks!!

awaiting-response bug

Most helpful comment

I believe it will be a simple matter of typeof window === 'undefined' :)

https://github.com/ctrlplusb/easy-peasy/blob/8514ad3ecfafd541fc8261b4468a494427496fbd/src/helpers.js#L49

export const persist = (model, config) => {
  // if we are not running in a browser context this becomes a no-op
  return typeof window === 'undefined' ? model : {
    ...model,
    [persistSymbol]: config,
  };
};

All 7 comments

Actually raises a point in that the persist API doesn't take into consideration you are operating on the server. I would expect that it should become a no-op on the server. Perhaps this fix would resolve your case.

@ctrlplusb, thanks for your response. Do you think there would be a workaround to keep SSR and persisting state currently? Maybe with Redux-persist?

Also, do you think making the persist API aware of the server will be straightforward, or will it imply many changes in the API?

Thanks!

I believe it will be a simple matter of typeof window === 'undefined' :)

https://github.com/ctrlplusb/easy-peasy/blob/8514ad3ecfafd541fc8261b4468a494427496fbd/src/helpers.js#L49

export const persist = (model, config) => {
  // if we are not running in a browser context this becomes a no-op
  return typeof window === 'undefined' ? model : {
    ...model,
    [persistSymbol]: config,
  };
};

Excited to try this :)

Hi @gabrilator

Sorry for the delay in this. I am wanting to look into it now, but feel like there could be a few different things going on here.

I was wondering if you would mind creating a minimal Next.js example on CodeSandbox that demonstrates the issue?

That would help me a lot to ensure we are fixing the correct problem.

No worries, @ctrlplusb ! Managed to do the change you mentioned and it works!

Was this page helpful?
0 / 5 - 0 ratings