Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Next.js Fetch data in HOC from server in SSG

I created new app with Next.js 9.3.1.

In old app with SSR, I can use getInitialProps function in HOC components (not in the page), so I can fetch data from server in the HOC component and from page. Like this https://gist.github.com/whoisryosuke/d034d3eaa0556e86349fb2634788a7a1

Example:

export default function withLayout(ComposedComponent) {
  return class WithLayout extends Component {
    static async getInitialProps(ctx) {
      console.log("ctxlayout fire");
      const { reduxStore, req } = ctx || {};
      const isServer = !!req;
      reduxStore.dispatch(actions.serverRenderClock(isServer));

      if (isServer)
        await reduxStore.dispatch(navigationActions.getListMenuAction("menu"));
      // Check if Page has a `getInitialProps`; if so, call it.
      const pageProps =
        ComposedComponent.getInitialProps &&
        (await ComposedComponent.getInitialProps(ctx));
      // Return props.
      return { ...pageProps };
    }

    render() {
      return (
        <div className="app__container">
          <Header />
          <Navbar />
          <ComposedComponent {...this.props} />
        </div>
      );
    }
  };
}

But in new version of Next.js with SSG, I can't find the way to use getStaticProps or getServerSideProps in HOC components. If I use getInitialProps in HOC (layout), I won't be able to use getStaticProps or getServerSideProps in child.

So, how can I use getStaticProps or getServerSideProps to fetch data and pre-render in both HOC component and page?

like image 793
Duy Hưng Androgyne Tenor Avatar asked Mar 23 '20 10:03

Duy Hưng Androgyne Tenor


People also ask

Can I use fetch in getStaticProps?

Alternatively, if you are not using API routes to fetch data, then the fetch() API can be used directly in getStaticProps to fetch data.

Is Next.js SSG?

The difference is that the fallback value is set to blocking. It means that when the user visits a page that is not statically generated yet, Next. js will return content after server-rendering is done for that particular page. SSG will be done in the background for the users that follow.

Is next CSR or SSR?

CSR in single-page React applications. Next. js is one way that you can leverage React to support server-side rendering (SSR). Likewise, Create React App is one way that you can leverage React to support client-side rendering (CSR).

Where can I fetch next data?

/pages/albums. jsx – Albums page will implement static site generation using getStaticProps, we will export the data fetching method along with the page component. We can send fetched data to the page component using props. Next Js will fetch all the albums at build time before the user's request.


Video Answer


1 Answers

Because getServerSideProps/getStaticProps need to be directly exported from the page component's file you have to extract that logic into a separate higher-order function (HOF) entirely.

You can keep the React component part as is in the withLayout HOC.

// hoc/with-layout.js
export default function withLayout(ComposedComponent) {
    return class WithLayout extends Component {
        render() {
            return (
                <div className="app__container">
                    <Header />
                    <Navbar />
                    <ComposedComponent {...this.props} />
                </div>
            );
        }
    };
}

The code that was inside getInitialProps will be moved to a separate HOF. This HOF will accept a getServerSideProps function as a param, and return another function where the logic will be.

// hoc/with-layout.js
export function withLayoutGSSP(gssp) {
    return async (context) => {
        //Add higher-order function logic here
        
        // Return by calling the passed `getServerSideProps` function
        return await gssp(context);
    };
}

This can then be used as follows in a page component that exports a getServerSideProps function (the same would be done for any page component where you'd want to reuse the HOC).

import withLayout, { withLayoutGSSP } from '<path-to>/hoc/with-layout'

const IndexPage = () => {
    // Your page component code
};

export const getServerSideProps = withLayoutGSSP(context => {
    // Your `getServerSideProps` code here
});

export default withLayout(IndexPage);

The same approach could be used for getStaticProps.

like image 178
juliomalves Avatar answered Oct 16 '22 19:10

juliomalves