Great! Now we have the session information stored in the req.session variable.

In particular, the user email is stored in the req.session.passport.user variable.

We could send any additional data we have stored, but for now we just have the email, and we sent that.

Now I want to get this user value from the server on the first page load we do, and store this value in our easy-peasy store.

Remember the pages/_app.js file we created in the previous module?

This is what we have in that file now:

pages/_app.js

import App from 'next/app'
import { StoreProvider } from 'easy-peasy'
import store from '../store'

export default class extends App {
  render() {
    const { Component, pageProps } = this.props
    return (
      <StoreProvider store={store}>
        <Component {...pageProps} />
      </StoreProvider>
    )
  }
}

I’m going to change this to a functional component, because I ran into problems doing what I am going to do. I just couldn’t figure out why it was not working, and I found an example online using a functional component, I tried and it worked, so I changed my code.

Things move fast with those technologies, and we must also be flexible enough to adapt to things we must tweak to make things work.

Without losing too much time on this, here’s the functional version:

pages/_app.js

import App from 'next/app'
import { StoreProvider } from 'easy-peasy'
import store from '../store'

function MyApp({ Component, pageProps, user }) {
  return (
    <StoreProvider store={store}>
      <Component {...pageProps} />
    </StoreProvider>
  )
}

export default MyApp

It’s pretty similar. I am going to add a getInitialProps function to this component:

pages/_app.js

MyApp.getInitialProps = async appContext => {
  const appProps = await App.getInitialProps(appContext)

  let user = null
  if (
    appContext.ctx.req &&
    appContext.ctx.req.session &&
    appContext.ctx.req.session.passport &&
    appContext.ctx.req.session.passport.user
  ) {
    user = appContext.ctx.req.session.passport.user
  }

  return { ...appProps, user: user }
}

Here we first call the current page getInitialProps. This makes sure that if the page implements its own getInitialProps, like pages/houses/[id].js, then we get those props back.

Then we check if we have the user information from the server, and if we do we return it as a prop.

We need a place to store this information. In our store.js file we already manage the modals state:

store.js

import { createStore, action } from 'easy-peasy'

export default createStore({
  modals: {
    showModal: false,
    showLoginModal: false,
    showRegistrationModal: false,
    setShowModal: action(state => {
      state.showModal = true
    }),
    setHideModal: action(state => {
      state.showModal = false
    }),
    setShowLoginModal: action(state => {
      state.showModal = true
      state.showLoginModal = true
      state.showRegistrationModal = false
    }),
    setShowRegistrationModal: action(state => {
      state.showModal = true
      state.showLoginModal = false
      state.showRegistrationModal = true
    })
  }
})

Let’s also add this user state at the end:

user: {
  user: null,
  setUser: action((state, payload) => {
    state.user = payload
  })
}

Now inside the MyApp body, we check if the user prop is set, and if it is we call the setUser action of the store:

function MyApp({ Component, pageProps, user }) {
  if (user) {
    store.getActions().user.setUser(user)
  }

  return (
    <StoreProvider store={store}>
      <Component {...pageProps} />
    </StoreProvider>
  )
}

Awesome!

Now in any component we can add:

import { useStoreState } from 'easy-peasy'

const user = useStoreState(state => state.user.user)

and we get the value of the user name (which also tells us the user is logged it).


Go to the next lesson