ReasonJun

Next.js : File System-based Routing (Shallow Routing) 본문

Frontend/Next.js

Next.js : File System-based Routing (Shallow Routing)

ReasonJun 2023. 6. 18. 19:24
728x90

In Next.js, "shallow routing" refers to a technique that allows you to update the URL displayed in the browser's address bar without actually re-rendering the entire page. This means that only the content within the page component will be refreshed while preserving the state of the surrounding components.

By default, when you navigate to a new page using Next.js' Link component or the router.push() function, the entire page is reloaded, including any data fetching and component lifecycle methods. This behavior is known as "full routing."

 

How to change url without running getServerSideProps / getStaticProps etc again, without losing current state.

 

However, in some cases, you may want to update the URL without performing a full page reload. This is particularly useful when you have complex UI components with their own state that you want to preserve during navigation. Shallow routing allows you to achieve this by using the shallow option provided by Next.js.

Here's an example of how to perform shallow routing using the Link component:

import Link from 'next/link';

const MyComponent = () => {
  return (
    <div>
      <Link href="/page" shallow>
        <a>Go to Page</a>
      </Link>
    </div>
  );
};

export default MyComponent;

By adding the shallow attribute to the Link component, you enable shallow routing. When the link is clicked, the URL will be updated, but the page component will not re-render. Instead, Next.js will call the componentDidUpdate lifecycle method, allowing you to handle the URL change and perform any necessary updates.

You can also use the router.push() function with the shallow option to achieve the same effect programmatically:

import { useRouter } from 'next/router';

const MyComponent = () => {
  const router = useRouter();

  const handleClick = () => {
    router.push('/page', undefined, { shallow: true });
  };

  return (
    <div>
      <button onClick={handleClick}>Go to Page</button>
    </div>
  );
};

export default MyComponent;

It's important to note that shallow routing has some limitations. Since the page component doesn't re-render, any data fetching or initialization that happens in the getStaticProps, getServerSideProps, or getInitialProps functions will not be triggered. If you need to update data or fetch new data when using shallow routing, you can manually make subsequent requests or handle the updates in the componentDidUpdate lifecycle method.

Overall, shallow routing in Next.js provides a way to update the URL without performing a full page reload, making it useful for preserving component state during navigation.

 

location.replace() => re-render

router.push()=> maintain state & data fetching

router.push(, undefined, {shallow : true }) => maintain state & do not data fetching

// <http://localhost:3000/setting/my/info?status=editing>
import Layout from '@/components/Layout'
import SubLayout from '@/components/SubLayout'
import { useRouter } from 'next/router'
import { useState } from 'react'

export async function getServerSideProps() {
  console.log('getServerSideProps')

  return {
    props: {},
  }
}

export default function CartDateSlug() {
  const router = useRouter()
  const [clicked, setClicked] = useState(false)
  const { status = 'initial' } = router.query
  return (
    <>
      {/* Do not maintain local state => re-render */}
      {/* Check : console.log('getServerSideProps') */}

      <main>
        <h1>My Info</h1>
        <h1>Clicked: {String(clicked)}</h1>
        <h1>Status: {status}</h1>
        <button
          onClick={() => {
            setClicked(!clicked)
            alert('edit')
            location.replace('/setting/my/info?status=editing')
          }}
        >
          edit(replace)
        </button>
        <br />
        {/* maintain local state / generate data fetching */}
        {/* Check : console.log('getServerSideProps') */}
        <button
          onClick={() => {
            setClicked(!clicked)
            alert('edit')
            router.push('/setting/my/info?status=editing')
          }}
        >
          edit(replace)
        </button>
        <br />
        {/* maintain local state / Do not generate data fetching */}
        {/* Do not check : console.log('getServerSideProps') */}
        <button
          onClick={() => {
            setClicked(!clicked)
            alert('edit')
            router.push('/setting/my/info?status=editing', undefined, {
              shallow: true,
            })
          }}
        >
          edit(replace)
        </button>
      </main>
    </>
  )
}

CartDateSlug.getLayout = function getLayout(page) {
  return (
    <Layout>
      <SubLayout>{page}</SubLayout>
    </Layout>
  )
}

 

728x90

'Frontend > Next.js' 카테고리의 다른 글

Next.js : <Link> vs <a> (Client-side navigation)  (0) 2023.06.19
Next.js : API Routes  (0) 2023.06.18
Next.js : File System-based Routing (Dynamic Routing )  (0) 2023.06.18
Next.js : Apply common layout  (0) 2023.06.18
Next.js : Image component  (0) 2023.06.18
Comments