1
votes

Best wishes, while I was using the local yoga server, and local docker container as a database, things worked very smoothly because data was loaded in split second, and thus... if someone was signed in, the name of the signed in person immediately appeared on client and server side as well.

Now that I deployed frontend, backend, and database on remote servers, it takes time to load the data. Due to this, The Sign In button stays for 3-4 seconds even if we were already signed in. And late the frontend realizes, that we were signed in and then shows our name.

This happens because we render the data only after we get the data. But when data comes late, the server-side code becomes outdated. Late updating client makes web app feel very lagging.

I am using Next.js

withData.js ????

import withApollo from 'next-with-apollo'
import ApolloClient from 'apollo-boost'

function createClient({ headers }) {

  return new ApolloClient({
    uri: `${process.env.ENDPOINT}/graphql`,
    request: operation => {
      operation.setContext({
        fetchOptions: {
          credentials: 'include',
        },
        headers
      })
    }
  })

}

export default withApollo(createClient);

User.js ????

import { Query } from 'react-apollo'
import gql from 'graphql-tag'
import PropTypes from 'prop-types'
import { client } from '../lib/withData'

export const CURRENT_USER_QUERY = gql`
  query {
    me {
      id
      name
      fname
      lname
      email
      phone
      bio
      previledge
      gender
      username
      birthday
      profilePicture
      signUpMethod
    }
  }
`

const User = props => (
  <Query {...props} query={CURRENT_USER_QUERY}>
    {payload => {
      return props.children(payload)
    }}
  </Query>
)

export default User

SignInButton.js ????

<User>
        {({data: {me}}) => (    

         { me ? <ProfileButton me={me} /> : <li style={{backgroundColor: '#ffffff', color: '#000000', borderRadius: '5px', padding: '5px 10px', zoom: '80%'}}><a href={`${meta.domain}/signin?intent=${this.props.router.asPath}`} style={{color: '#000000'}}>⚡️???? {this.signInText}</a></li> }

        )}
</User>

pages/_app.js ????

import App, { Container } from 'next/app'
import { ApolloProvider } from 'react-apollo'

import withData from '../src/lib/withData'
import Page from '../src/components/Page'

class Wrapper extends App {

    static getInitialProps({Component, ctx}){

        let pageProps = {}
        if(Component.getInitialProps){
            pageProps = Component.getInitialProps(ctx)
        }

        // This exposes query to the user
        pageProps.query = ctx.query
        return { pageProps }

    }

    render() {
        const { Component, apollo, pageProps } = this.props
        return (
            <Container>
                <ApolloProvider client={apollo}>
                    <Page>
                        <div className="super_container"><Component {...pageProps} /></div>
                    </Page>
                </ApolloProvider>
            </Container>
        )
    }

}


export default withData(Wrapper)

How do I render the data from react-apollo on the server side?


Found these resources but difficult to implement with the stack I use.

https://bessey.dev/blog/2019/01/02/apollo-graphql-hypernova/

https://github.com/i18next/react-i18next/issues/593

https://shaleenjain.com/blog/nextjs-apollo-prefetch/

1

1 Answers

1
votes

If you want SSR by query so you can populate head and other stuff directly in serverSide, you need to make the query directly in You need to create the query inside the GetInitialProps function like this :

Page.getInitialProps = async ({
  apolloClient, query, children, router, href
}) => {
  const { data, error, loading } = await apolloClient.query({ query: LIVRE_QUERY, variables: { slug: query.titre } })
  if (error) {
    return <div>Erreur</div>
  }
  return { data, error, loading }
}