본문 바로가기
개발/Next.js

Shallow routing을 사용하면 리렌더링, 데이터페칭없이 페이지이동 가능

by 안뇽! 2022. 9. 16.
반응형

 

구구절절 설명하기보다 코드랑 gif로 설명이 가능하다.

 

// src/pages/settings/my/[info].js

import { useRouter } from 'next/router'
import React, { useState } from 'react'
import GeneralHeader from '../../../components/GeneralHeader'
import Layout from '../../../components/Layout'

//서버에서 data fetching 여부를 확인하기 위해 콘솔로그만 작성
export async function getStaticProps() {
  console.log('server')
  return {
    props: {},
  }
}

//getStaticPaths는 url이 동적으로 변하기 때문에 사용
export async function getStaticPaths() {
  return {
    paths: [{ params: { info: 'info' } }],
    fallback: true,
  }
}

export default function MyInfo() {
  const router = useRouter()
  const [clicked, setClicked] = useState(false)
  const { status = 'initial' } = router.query
  return (
    <>
      <h1 className="title">My Info</h1>
      <h1 className="title">Clicked {String(clicked)}</h1>
      <h1 className="title">Status {status}</h1>
      <hr></hr>
      <button
        onClick={() => {
          alert('edit')
          setClicked(true)
          location.replace('/settings/my/info')
        }}
      >
        go to 'settings/my/info'
      </button>
      <hr></hr>
      <button
        onClick={() => {
          alert('edit')
          setClicked(true)
          location.replace('/settings/my/info?status=editing')
        }}
      >
        edit(replace) - location.replace =&gt; 다시 리렌더링된다. 서버요청 받음
      </button>
      <hr></hr>
      <button
        onClick={() => {
          alert('edit')
          setClicked(true)
          router.push('/settings/my/info?status=editing')
        }}
      >
        edit(replace) - router.push -&gt; 리렌더링 되지 않음. 서버요청 받음
        (date fetching일어남)
      </button>
      <hr></hr>
      <button
        onClick={() => {
          alert('edit')
          setClicked(true)
          router.push('/settings/my/io?status=editing', undefined, {
            shallow: true,
          })
        }}
      >
        edit(replace) - router.push -&gt; 리렌더링 되지 않음. 서버요청 x 즉,
        data fetching 안됨
      </button>
    </>
  )
}

MyInfo.getLayout = function getLayout(page) {
  return (
    <Layout>
      <GeneralHeader>{page}</GeneralHeader>
    </Layout>
  )
}

위의 코드로 만든 화면이다.

 

유심히 볼 점

1. 리렌더링 여부

버튼을 클릭하면 onClick에 의해 clicked가 true가 된다.

 

이때 두번째 줄은 Clicked true로 바뀔 것이다.

 

이때 리렌더링이 된다면 곧바로 상태 clicked가 초기값이 되어 두번째줄은 Clicked false로 돌아올 것이다.

 

export default function MyInfo() {

  const [clicked, setClicked] = useState(false) // clicked의 초기값은 false임


  return (
    <>
      <h1 className="title">My Info</h1>
      <h1 className="title">Clicked {String(clicked)}</h1>
      <h1 className="title">Status {status}</h1>
      
       <button
        onClick={() => {
          alert('edit')
          setClicked(true)
          location.replace('/settings/my/info?status=editing')
        }}
      >

2. data fetching 여부

data fetching이 일어난다면 서버 터미널에 console.log('server')가 찍힐 것이다.

export async function getStaticProps() {
  console.log('server')
  return {
    props: {},
  }
}

 

 

url변경 방식 3가지

  1. location.replace('..') : 리렌더링시키고 서버요청도 받음(data fetching 일어남)
  2. router.push('..') : 리렌더링은 되지 않지만 서버요청은 받는다(data fetching일어남)
  3. router.push('..',as,{shallow:true}) : 리렌더링 안되고, 서버요청도x => 페이지이동만 함

 

GIF를 통해 위의 1,2,3 번의 각 결과를 확인해보자!

1. location.replace()

<button
        onClick={() => {
          alert('edit')
          setClicked(true)
          location.replace('/settings/my/info')
        }}
      >
        go to 'settings/my/info'
      </button>

location.replace로 페이지 변경시

alert를 확인한 후에 "Clciked true"로 변했다가 리렌더링되면서 초기화면 "Clicked false"로 변한다.

이는 리렌더링이 됨을 보여준다.

 

2. router.push('..')

<button
        onClick={() => {
          alert('edit')
          setClicked(true)
          router.push('/settings/my/io?status=editing')
        }}
      >
        edit(replace) - router.push -&gt; 리렌더링 되지 않음. 서버요청 x 즉,
        data fetching 안됨
      </button>

router.push('..')

Clicked true가 그대로 유지되는것으로 보았을 때, 리렌더링이 되지는 않음을 확인할 수 있다.

그리고 로그가 찍히는것을 확인할 수 있음.(data fetching 일어남)

 

3. router.push('..',..,{shallow:true})

<button
        onClick={() => {
          alert('edit')
          setClicked(true)
          router.push('/settings/my/io?status=editing', undefined, {
            shallow: true,
          })
        }}
      >
        edit(replace) - router.push -&gt; 리렌더링 되지 않음. 서버요청 x 즉,
        data fetching 안됨
      </button>

router.push('..',..,{shallow:true})

Clicked true가 그대로 유지되는것으로 보았을 때, 리렌더링이 되지는 않음을 확인할 수 있다.

서버에서도 로그가 따로 찍히지 않는다.

 

 

즉, shallow routing은 리렌더링이 없고, data fetching도 없이 페이지만 이동함을 알 수 있다.

반응형