When I implemented the logic of fetching the authenticated user and setting it to the Redux state inside the App.getInitialProps
method and accessing that user from the state within any Next.js page, I encountered an error when navigating between pages.
Warning: Cannot update a component (`HomeScreen`) while rendering a different component (`App`).
...
export const HomeScreen = () => {
const user = useAppSelector(selectCurrentUser);
...
Here is the problem. Inside App.getInitialProps
I'm fetching the API endpoint using RTK Query to retrieve the auth user from the cookie and when the query is fulfilled user adds to the state. And that causes that error in the console.
// _app.tsx
import '@/assets/styles/globals.scss';
import type { NextPage } from 'next';
import type { AppContext, AppProps } from 'next/app';
import { Provider } from 'react-redux';
import { wrapper } from '@/store';
import { me } from '@/store/auth/auth.api';
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
getLayout?: (page: React.ReactElement) => React.ReactNode;
};
type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout;
};
function App({ Component, ...rest }: AppPropsWithLayout) {
const {
store,
props: { pageProps },
} = wrapper.useWrappedStore(rest);
const getLayout = Component.getLayout ?? ((page) => page);
return (
<Provider store={store}>{getLayout(<Component {...pageProps} />)}</Provider>
);
}
App.getInitialProps = wrapper.getInitialAppProps(
(store) =>
async ({ ctx, Component }: AppContext) => {
// That string causes the error
await store.dispatch(me.initiate());
return {
pageProps: {
...(Component.getInitialProps
? await Component.getInitialProps({ ...ctx, store })
: {}),
},
};
},
);
export default App;
The query that I initiate inside App.getInitialProps:
me: builder.query<User, void>({
query: () => ({
url: 'auth/me',
method: 'GET',
}),
async onQueryStarted(_args, { dispatch, queryFulfilled }) {
try {
const { data } = await queryFulfilled;
dispatch(setCredentials({ user: data }));
} catch (err) {
// Do nothing
}
},
}),