I'm trying to create a HOC for withCurrentUser like this:
import React, { Component } from 'react';
export default WrappedComponent =>
// eslint-disable-next-line react/prefer-stateless-function
class extends Component {
static getInitialProps({ apollo }) {
console.log('it called me');
console.log(apollo);
return { hello: "world" };
}
render() {
return (
<>
<h1>hello from withCurrentUser</h1>
<WrappedComponent {...this.props} />
</>
);
}
};
and then trying to use like this:
import React from 'react';
import withCurrentUser from '../../hocs/withCurrentUser';
const NavBar = ({ hello }) => <h1>NavBar {hello}</h1>;
export default withCurrentUser(NavBar);
But it's not calling getInitialProps. What am I doing wrong?
'getInitialProps' would only be called when the component is in the folder './pages'. Have you put the file of the second part of code exactly in './pages'?
No, it's a NavBar component. The idea was to have a NavBar with the current user using a HOC technique as Spectrum.chat does. But apparently it doesn't work as I expected.
I guess we'll have to make the warning clearer here: https://github.com/zeit/next.js#fetching-data-and-component-lifecycle
Note: getInitialProps can not be used in children components. Only in pages.
@timneutkens I did it different, I don't actually need to get the apollo client from getInitialprops, I can just make usage of the Query component and it will, the reason for that is because I'm wrapping the _app.js with the withApollo HOC that has the ApolloProvider in it.
I just created a HOC using Query and called the WrappedComponent passing the current user data as props.
I wrapped a page with a withAuth HOC and the page's getInitialProps cannot be called as a result.The authentication function using the withAuth HOC works; however, the Contact's getInitialProps function is not called as a result
Anyway to work around this?
Contact Page
import Layout from "../components/Layout";
import { withAuth } from "../services/withAuth";
class Contact extends React.Component {
static async getInitialProps(ctx) {
console.log("@contact authenticated ", ctx);
return {};
}
render() {
return (
<Layout>
<p>hey there</p>
<a href="mailto:[email protected]">[email protected]</a>
</Layout>
);
}
}
export default withAuth(Contact);
withAuth HOC
import { ME } from "../graphql/queries";
import redirect from "../lib/redirect";
export const withAuth = C => {
class AuthComponent extends React.Component {
static async getInitialProps(ctx) {
const response = await ctx.apolloClient.query({ query: ME });
console.log("@withAuth ", response);
if (!response || !response.data || !response.data.me) {
redirect(ctx, "/");
return {
me: null
};
}
return {
me: response.data.me
};
}
render() {
return <C {...this.props} />;
}
}
return AuthComponent;
};
You have to call C.getInitialProps(...) in HOC.getInitialProps(...);
const pageProps = await C.getInitialProps && C.getInitialProps(ctx);
Hi @jim-king-2000 , can't seem to work. it throws a circular reference error
Hi @jim-king-2000 , it works now. i passed the entire ctx object to the return value hence it throws the circular reference error. however, if i destructure the ctx and pass on only the destructured values, it works fine. Thanks for your sharing
@myhendry can you show me code how you destructed the ct and passed only destructed values I am facing similar issue
@yalamber , here's the stackoverflow issue I opened https://stackoverflow.com/questions/55869475/using-getinitialprops-with-hoc-which-also-contains-getinitialprops/55873165#55873165
@myhendry I didn't notice anything destructuring on the stackoverflow issue. Please she'd more light
@myhendry You need to contain the static methods in the HOC.
export function withAuth (WrappedComponent) {
return class extends Component {
constructor(props) {
super(props)
}
static getInitialProps = WrappedComponent.getInitialProps
render () {
return <WrappedComponent {...this.props} />
}
}
}
Here is the official docs from React:
https://reactjs.org/docs/higher-order-components.html#static-methods-must-be-copied-over
Most helpful comment
I guess we'll have to make the warning clearer here: https://github.com/zeit/next.js#fetching-data-and-component-lifecycle