Reputation: 491
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?
Upvotes: 17
Views: 4120
Reputation: 50278
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
.
Upvotes: 3