javascriptreactjsnext.jsreact-aria

usePreventScroll causes useLayoutEffect warning in Nextjs


I'm learning Next.js and I'm trying to integrate the @react-aria/overlays package in my project. I have a layout component, where I'm simply invoking the usePreventScroll method like this:

   usePreventScroll({
        isDisabled: true
    });

This layout component is used in my _app.js.

import { useEffect } from 'react'
import { useRouter } from 'next/router'
import * as gtag from '../lib/gtag'

import 'styles/vendor.scss';
import 'styles/globals.scss';

import Layout from 'components/layout';

import { SSRProvider } from '@react-aria/ssr';

const App = ({ Component, pageProps }) => {
  return (
      <SSRProvider>
        <Layout>
          <Component {...pageProps} />
        </Layout>
      </SSRProvider>
  )
}

export default App;

When going to my browser and loading a page, it gives me the following error:

Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://reactjs.org/link/uselayouteffect-ssr for common fixes.
    at Layout (/home/bas/projects/test-website/build/server/pages/_app.js:718:3)
    at div
    at $c5f9596976ab8bd94c5879001549a3e$var$OverlayContainerDOM (/home/bas/projects/test-website/node_modules/@react-aria/overlays/dist/main.js:864:7)
    at ModalProvider (/home/bas/projects/test-website/node_modules/@react-aria/overlays/dist/main.js:810:5)
    at OverlayProvider
    at SSRProvider (/home/bas/projects/test-website/node_modules/@react-aria/ssr/dist/main.js:33:13)
    at UIContextProvider (/home/bas/projects/test-website/build/server/pages/_app.js:1144:74)
    at ManagedUIContext (/home/bas/projects/test-website/build/server/pages/_app.js:1105:3)
    at App (/home/bas/projects/test-website/build/server/pages/_app.js:5171:3)
    at AppContainer (/home/bas/projects/test-website/node_modules/next/dist/next-server/server/render.js:23:748)

What's the problem here and how would I be able to solve it?

I tried wrapping the the Layout component in the packages <SSRProvider>.


Solution

  • Next js is computes your 1st page on server. so it does not understand browser scroll or localstorage or other browser api. you can add a check in your code block if window object is present or execution is running in server and then execute usePreventDefault.

        import {useIsSSR} from '@react-aria/ssr';
    
        function Layout() {
           let isSSR = useIsSSR();
     
           useEffect(() => {
             !isSSR && usePreventScroll({ ... }) 
           }, [isSSR])
        }