nextjs app rerenders on routing to any page

Viewed 72

I am using nextjs version 12.1.6, react-dom version 18.0.5, next-auth 4.6.1, I have an application with 2 routes at the moment, an index page and a login page, when I route from the index page to the login page and vice versa, my whole app rerenders, I have react-profiler and the given reason is context change, I assume its have to do something with the SessionProvider from next-auth but why it rerenders my whole app?

enter image description here

as you can see I have a HeaderComponent that did NOT rerendered, this is because I used React.memo on it, but I dont want to wrap all my components in React.memo, also this component is used inside on a Layout component pages/_app.tsx

my _app.tsx

function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <Head>
          <title>foo</title>
          <meta name="description" content="Generated by create next app" />
          <link rel="icon" href="/favicon.ico" />
      </Head>
  
      <SessionProvider session={ pageProps.session }>
        <LayoutComponent>
          <Component {...pageProps} />
        </LayoutComponent>  
      </SessionProvider>  
    </>    
  );
}

also I am using nextjs Link jsx element for routing

my LayoutComponent:

const LayoutComponent = ({ children }: PropsWithChildren) => {
    return (
        <>
            <HeaderComponent 
                homePath='/'
                signinPath='/auth/signin'
                aboutPath='/about'
            />
                <main>
                    { children }
                </main>
            <FooterComponent />
        </>
    );
}

export default LayoutComponent;
1 Answers

Okay, I'll give it a shot.

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

export default MyApp

Component in the code above is your page (Login/Index). Whenever you navigate to a page from another one by clicking a Next Js link, your Login/Index component will be fetched from the server and then React will compare the new and old component and re-render since they are different.

function MyApp({ Component, pageProps }) {
  return (
    <VerticalLayout>
      <Component {...pageProps} />
    </VerticalLayout>
  )
}

export default MyApp

If you put your page component between opening an closing tags of a layout component like above, only the corresponding component will be re-render again but VerticalLayout will stay untouched.

const VerticalLayout = ({children}) => {
  return (
    <div id="layout-wrapper">
      <HeaderComponent />
      <main>
        <Sidebar />
        <div className="main-content">{children}</div>
      </main>
      <FooterComponent />
    </div>
  )
})

You can then place your header/footer components in that component like above. So that they will not be re-render when you navigate to a different page.

Related