Skip to content

Instantly share code, notes, and snippets.

View khg0712's full-sized avatar
🎯
Focusing

Hugo Kim khg0712

🎯
Focusing
View GitHub Profile
// SSR μ‹œμ μ— Router 싱글톀에 μ ‘κ·Όν•  λ•Œ Next.js page μ»΄ν¬λ„ŒνŠΈ μ˜ˆμ‹œ
import Router from 'next/router'
export default function page() {
return (
<div>
{/* μ•„λž˜ μ—λŸ¬ λ°œμƒ
* Error: No router instance found.
* You should only use "next/router" on the client side of your app.
* /}
// SSR μ½”λ“œ
// packages/next/server/render.tsx
// renderToHTML의 μΈν„°νŽ˜μ΄μŠ€λŠ” μƒλž΅.
// https://github.com/vercel/next.js/blob/v12.3.4/packages/next/server/render.tsx#L351
export async function renderToHTML() {
// CSRκ³Ό λ‹€λ₯΄κ²Œ SSR에선 ServerRouterλΌλŠ” λ³„κ°œμ˜ class둜 Routerλ₯Ό λ§Œλ“ λ‹€.
// ServerRouter parameterλŠ” μƒλž΅.
const router = new ServerRouter()
// packages/next/client/index.ts
// Router 싱글톀을 μ €μž₯ν•˜λŠ” μ „μ—­ 객체
// https://github.com/vercel/next.js/blob/v12.3.4/packages/next/client/index.tsx#L67
export let router: Router
// AppContainerμ—μ„œ RouterContext에 Router 싱글톀 μ£Όμž…ν•˜λŠ” μ½”λ“œ
// https://github.com/vercel/next.js/blob/v12.3.4/packages/next/client/index.tsx#L296
function AppContainer({
children,
// packages/next/client/router.ts
// import Router from 'next/router' ν–ˆμ„ λ•Œ μ ‘κ·Όν•˜λŠ” κ°’.
// Export the singletonRouter and this is the public API.
export default singletonRouter as SingletonRouter
// packages/next/client/router.ts
// Router 싱글톀을 μ €μž₯ν•˜λŠ” 객체
// https://github.com/vercel/next.js/blob/v12.3.4/packages/next/client/router.ts#L20
const singletonRouter: SingletonRouterBase = {
router: null, // holds the actual router instance
readyCallbacks: [],
ready(cb: () => void) {
if (this.router) return cb()
if (typeof window !== 'undefined') {
// packages/next/client/index.ts
// Router 싱글톀을 μ €μž₯ν•˜λŠ” μ „μ—­ 객체
// https://github.com/vercel/next.js/blob/v12.3.4/packages/next/client/index.tsx#L67
export let router: Router
// hydrate ν•¨μˆ˜μ—μ„œ Router 싱글톀이 μ΄ˆκΈ°ν™”(createRouter)λ˜λŠ” μ½”λ“œ 호좜
// https://github.com/vercel/next.js/blob/v12.3.4/packages/next/client/index.tsx#L863
export async function hydrate(opts?: { beforeRender?: () => Promise<void> }) {
// ...
// packages/next/client/with-router.tsx
// withRouter μ½”λ“œ
// https://github.com/vercel/next.js/blob/v12.3.4/packages/next/client/with-router.tsx#L19
import { useRouter } from './router'
export default function withRouter<
P extends WithRouterProps,
C extends BaseContext = NextPageContext
>(
// packages/next/client/router.ts
// useRouter μ½”λ“œ
// https://github.com/vercel/next.js/blob/v12.3.4/packages/next/client/router.ts#L132
export function useRouter(): NextRouter {
return React.useContext(RouterContext)
}
// packages/next/client/index.tsx
// https://github.com/vercel/next.js/blob/v12.3.4/packages/next/client/index.tsx
// 졜초 hydration을 μœ„ν•΄μ„œ μ‚¬μš©
// λ‚΄λΆ€μ—μ„œ render ν•¨μˆ˜ 호좜
// ν•¨μˆ˜ λ‚΄λΆ€λŠ” μƒλž΅
// https://github.com/vercel/next.js/blob/v12.3.4/packages/next/client/index.tsx#L756
export async function hydrate(opts?: { beforeRender?: () => Promise<void> }) {}
// packages/next/client/next.js
// https://github.com/vercel/next.js/blob/v12.3.4/packages/next/client/next.js#L12
// Next.js client side initialize μ½”λ“œ
initialize({})
.then(() => hydrate())
.catch(console.error)