withRouter passes prop router: null
to wrapped component whereas in next 9.1.2 it always passed the right object (with query, etc.))
import { withRouter } from "next/router";
const Component = ({router}) => {
console.log(router); // will be null on first render
return <div>.....</div>
}
withRouter(Component);
see component above
withRouter
always injects relevant data)
OS: macOs
Version of Next.js: 9.1.3
This bug was not present in 9.1.2 9.1.1. (we skipped 9.1.2)
https://github.com/zeit/next.js/issues/9105#issuecomment-548343173 suggested that this bug was already present in 9.1.2
have to stick to 9.1.1 now
Always provide a full reproduction when creating GitHub issues. This is not enough to reproduce.
Are you using Apollo or urql by any chance?
@timneutkens yes, i am using apollo. I just started a reproduction and it does not occure on a fresh nextjs (which was to be expected). So i also thought it has to do with apollo. The apollo client is initialized in _app.jsx according to the older examples (the newer examples don't extend _app anymore, but require you to use a HOC on every page)
You'll have to use AppTree similarly to the newer examples. That's probably where it broke (the older example was doing non-standard behavior).
@timneutkens thx, this seems to work.
For other falling into the same issue:
in withApolloClient
-HOC, in getMarkupFromTree, it should use <AppTree />
not <App />
it looks something like:
import { getMarkupFromTree } from "@apollo/react-ssr";
import { ApolloClient } from "apollo-boost";
import Head from "next/head";
import nookies from "nookies";
import React from "react";
import { renderToString } from "react-dom/server";
import { initApollo } from "./initApollo";
export default (App) => {
return class Apollo extends React.Component {
public static displayName = "withApollo(App)";
public static async getInitialProps(appContext) {
let appProps = {};
const { AppTree } = appContext;
if (App.getInitialProps) {
appProps = await App.getInitialProps(appContext);
}
const { Component, router, ctx } = appContext;
const apollo = createApollo(ctx);
ctx.apollo = apollo;
if (!process.browser) {
try {
// Run all GraphQL queries
await getMarkupFromTree({
renderFunction: renderToString,
tree: (
<AppTree {...appProps} Component={Component} router={router} apolloClient={apollo} />
),
});
} catch (error) {
// Prevent Apollo Client GraphQL errors from crashing SSR.
// Handle them in components via the data.error prop:
// https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-query-data-error
// tslint:disable-next-line:no-console
console.error("Error while running `getMarkupFromTree`", error);
}
// getDataFromTree / getMarkupFromTree does not call componentWillUnmount
// head side effect therefore need to be cleared manually
Head.rewind();
}
// Extract query data from the Apollo store
const apolloState = apollo.cache.extract();
return {
...appProps,
apolloState,
};
}
private apolloClient: ApolloClient<any>;
constructor(props) {
super(props);
this.apolloClient = initApollo(props.apolloState);
}
public render() {
return <App {...this.props} apolloClient={this.apolloClient} />;
}
};
};
@timneutkens sadly, i did not realize, that now SSR with apollo is broken. on SSR all components using apollo now render in loading state and apollo.cache.extract();
returns an empty object.
also https://github.com/zeit/next.js/issues/9336 seems to have a similar problem.
I now will revert to 9.1.1 and stick to that for the moment, because i think others have similar problems and there was an accidental breaking change between 9.1.1 and 9.1.3
A note in case anyone makes the same mistake I did:
Auto imports could pull withRouter from "next/dist/client/with-router" which will cause this issue.
To correct this make sure you import withRouter from "next/router";
A note in case anyone makes the same mistake I did:
Auto imports could pull withRouter from "next/dist/client/with-router" which will cause this issue.To correct this make sure you import withRouter from "next/router";
i only include import { WithRouterProps } from "next/dist/client/with-router";
, withRouter
is always imported with import { withRouter } from "next/router";
A note in case anyone makes the same mistake I did:
Auto imports could pull withRouter from "next/dist/client/with-router" which will cause this issue.To correct this make sure you import withRouter from "next/router";
Exactly what happened to me too!
For anyone having this issue, in my case, I got this issue using useRouter
's hook in a component nested inside a header section (next/head
).
Moving the component outside of the head section solved the issue.
I'm using next 9.3.4.
Most helpful comment
A note in case anyone makes the same mistake I did:
Auto imports could pull withRouter from "next/dist/client/with-router" which will cause this issue.
To correct this make sure you import withRouter from "next/router";