next.js의 next/router 패키지에서 useRouter와 Router를 제공한다.
두 가지 사용법과 차이에 대해서 알아봤다.
useRouter
import { useEffect } from 'react'
import { useRouter } from 'next/router'
// Here you would fetch and return the user
const useUser = () => ({ user: null, loading: false })
export default function Page() {
const { user, loading } = useUser()
const router = useRouter()
useEffect(() => {
if (!(user || loading)) {
router.push('/login')
}
}, [user, loading, router])
return <p>Redirecting...</p>
}
useRouter()는 next.js에서 브라우저를 라우팅 할 수 있는 hook이다.
위 예시로 보면 useEffect는 user, loading, router에 디펜던시가 있으므로 해당 값이 변하면 useEffect가 동작한다.
따라서 router가 변해도 useEffect가 돌게 된다.
Router
import Router from 'next/router';
export function test() {
Router.push('/');
}
Router도 useRouter와 기능은 완전히 동일하다. 사용법도 기본적으로 같다.
차이
왜 같은 기능을 하는 Router와 useRouter를 제공하는 걸까? 궁금했다.
next.js의 router 내부 코드이다. 코드를 보면 useRouter와 Router가 완전히 동일함을 알 수 있다.
다만 useRouter는 Context API를 이용해서 hook 형태로 제공하는 것 뿐이다.
useRouter는 리액트의 라이프사이클에 따라 상태를 업데이트하고
Router는 항상 최신 상태를 가리킨다.
이 차이가 가장 핵심이다.
Router는 클래스형, 함수형 컴포넌트에서 모두 사용될 수 있고
useRouter는 함수형 컴포넌트에서만 리액트 라이프사이클에 따라 사용된다. (hook의 제약)
next.js에서는 함수형 컴포넌트에선 useRouter 사용을 권장하고 있다.
왜냐하면 라이프사이클에 맞춰서 상태가 업데이트 되기 때문에 다른 state, hook과 맞춰서 동작을 예측하기가 쉬워지기 때문이다.
Router는 언제 활용해야 할까?
이 포스트를 작성하게 된 것은 전역객체인 Router를 사용할 일이 생겨서다.
Router는 useRouter와 기능적으로 같다.
다만 Router는 전역 객체이고 싱글턴이다. 그래서 항상 최신 상태를 보장한다.
그리고 Router는 함수형 컴포넌트가 아닌 구역에서도 사용이 가능하다.
리액트를 벗어난 영역의 코드에서도 실행이 가능하단 뜻이다.
위 조건이 필요한 경우에 사용하면 된다.
내가 활용한 경우는 웹뷰인데
ios/aos 개발자가 웹뷰 페이지를 이동시킬 때
웹뷰 페이지를 강제로 이동시킬 수도 있지만
이렇게 되면 히스토리가 꼬이게 된다.
그래서 앱에서 직접적으로 웹뷰의 url를 건드리는 게 아니라
웹뷰의 자바스크립트 전역 함수를 실행시키고 (evaluateJavascript)
그 전역 함수에서 next.js의 Router로 이동시키게 하여
웹에서 페이지 이동을 제어하게 했다.
참고
https://github.com/vercel/next.js/blob/canary/packages/next/client/router.ts
'공부' 카테고리의 다른 글
[Next.js] 브라우저 뒤로가기 막기 beforePopState 문제점 (1) | 2022.09.20 |
---|---|
Edge Side Rendering (SSR vs CSR vs ESR) (1) | 2022.09.09 |
Edge Computing (FeConf 2022) (0) | 2022.09.02 |
HTTP 2.0 (0) | 2022.08.15 |
HTTP 1.1 Connection (0) | 2022.08.15 |