라이브러리 - React Router v7

2026. 5. 11. 15:55·📂 라이브러리

React Router v7

 

 

✅ Layout


<routes.ts>

    ...prefix("/:productId", [
      index("features/products/pages/product-redirect-page.tsx"),
      layout("features/products/layouts/product-overview-layout.tsx", [
        route("/overview", "features/products/pages/product-overview-page.tsx"),
        ...prefix("/reviews", [
          index("features/products/pages/product-reviews-page.tsx"),
          route("/new", "features/products/pages/new-product-review-page.tsx"),
        ]),
      ]),
    ]),

layout fn을 사용하여 layout 파일을 지정하고 해당 route내에 Outlet으로 rendering할 children route들을 넣으면 된다.

 

<product-overview-layout.tsx>

import { ChevronUpIcon, StarIcon } from "lucide-react";
import { Link, Outlet } from "react-router";
import { Button } from "~/common/components/ui/button";

export default function ProductOverviewLayout() {
  return (
    <div className="space-y-10">
      <div className="flex justify-between">
        <div className="flex gap-10">
          <div className="bg-primary/50 size-40 rounded-xl shadow-xl"></div>
          <div>
            <h1 className="text-5xl font-bold">Product Name</h1>
            <p className="text-2xl font-light">Product description</p>
            <div className="mt-5 flex items-center gap-2">
              <div className="flex text-yellow-400">
                {Array.from({ length: 5 }).map((_, index) => (
                  <StarIcon className="size-4" fill="currentColor" />
                ))}
              </div>
              <span className="text-muted-foreground">100 reviews</span>
            </div>
          </div>
        </div>
        <div className="flex gap-5">
          <Button
            variant={"secondary"}
            size={"lg"}
            className="h-14 px-10 text-lg"
          >
            Visit website
          </Button>
          <Button size={"lg"} className="h-14 px-10 text-lg">
            <ChevronUpIcon className="size-4" />
            Upvote (100)
          </Button>
        </div>
      </div>
      <div className="flex gap-2">
        <Button variant={"outline"} asChild>
          <Link to={`/products/${productId}/overview`}>Overview</Link>
        </Button>
        <Button variant={"outline"} asChild>
          <Link to={`/products/${productId}/reviews`}>Reviews</Link>
        </Button>
      </div>
      <div>
        <Outlet />
      </div>
    </div>
  );
}

 

 

✅ NavLink


import { ChevronUpIcon, StarIcon } from "lucide-react";
import { NavLink, Outlet } from "react-router";
import { Button, buttonVariants } from "~/common/components/ui/button";
import { cn } from "~/lib/utils";

export default function ProductOverviewLayout() {
  return (
    <div className="space-y-10">
      <div className="flex justify-between">
        <div className="flex gap-10">
          <div className="bg-primary/50 size-40 rounded-xl shadow-xl"></div>
          <div>
            <h1 className="text-5xl font-bold">Product Name</h1>
            <p className="text-2xl font-light">Product description</p>
            <div className="mt-5 flex items-center gap-2">
              <div className="flex text-yellow-400">
                {Array.from({ length: 5 }).map((_, index) => (
                  <StarIcon
                    key={index}
                    className="size-4"
                    fill="currentColor"
                  />
                ))}
              </div>
              <span className="text-muted-foreground">100 reviews</span>
            </div>
          </div>
        </div>
        <div className="flex gap-5">
          <Button
            variant={"secondary"}
            size={"lg"}
            className="h-14 px-10 text-lg"
          >
            Visit website
          </Button>
          <Button size={"lg"} className="h-14 px-10 text-lg">
            <ChevronUpIcon className="size-4" />
            Upvote (100)
          </Button>
        </div>
      </div>
      <div className="flex gap-2">
        <NavLink
          className={({ isActive }) =>
            cn(
              buttonVariants({ variant: "outline" }),
              isActive && "bg-accent text-foreground",
            )
          }
          to={`/products/productId-0/overview`}
        >
          Overview
        </NavLink>
        <NavLink
          className={({ isActive }) =>
            cn(
              buttonVariants({ variant: "outline" }),
              isActive && "bg-accent text-foreground",
            )
          }
          to={`/products/productId-0/reviews`}
        >
          Reviews
        </NavLink>
      </div>
      <div>
        <Outlet />
      </div>
    </div>
  );
}

 

'📂 라이브러리' 카테고리의 다른 글

라이브러리 - Magic UI  (1) 2026.05.21
라이브러리 - Simple Icons  (0) 2026.05.15
라이브러리 - Luxon  (0) 2026.05.04
라이브러리 - Lucide React  (0) 2026.04.29
라이브러리 - Shadcn/ui  (0) 2026.04.27
'📂 라이브러리' 카테고리의 다른 글
  • 라이브러리 - Magic UI
  • 라이브러리 - Simple Icons
  • 라이브러리 - Luxon
  • 라이브러리 - Lucide React
j2yonghwa
j2yonghwa
Trying to be a fullstack developer 🚀
  • j2yonghwa
    j2yonghwa
    j2yonghwa
  • 전체
    오늘
    어제
    • 분류 전체보기 (156)
      • ⏰ Daily WakaTime (1)
      • 🏖️ 노마드코더 (2)
      • 🍺 Dev Setup (3)
      • 🔭 Tech Info (1)
      • 🚫 Error (1)
      • 📂 라이브러리 (23)
      • ♣️ Next.js 14 (10)
      • ♠️ Next.js 12 (20)
      • 🛸 React Native (12)
      • 🦋 TypeScript (1)
      • 🐍 Python (2)
      • 🌊 TailwindCSS (4)
      • 🧩 SQL (25)
      • 💎 Prisma (5)
      • 🌱 MongoDB (4)
      • 🎯 Redis (1)
      • 🧬 GraphQL (2)
      • 🔥 Firebase (7)
      • 💸 Third-Party Services (2)
      • 🕸️ Web (1)
      • 🏆 코딩테스트 (23)
      • 📙 모딥다 (5)
      • 📗 코테 합격자 되기 -JS- (0)
      • 📘 클린코드 (0)
      • 🍯 꿀팁 🐝 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃헙
  • 공지사항

  • 인기 글

  • 태그

    Prisma
    라이브러리
    next.js 14
    모딥다
    Python
    React Native
    자바스크립트
    Next.js
    SQL
    react router
    next.js 12
    API
    코딩테스트 입문
    PostgreSQL
    tailwindcss
    MySQL
    Firebase
    dev setup
    0레벨
    mongoDB
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
j2yonghwa
라이브러리 - React Router v7
상단으로

티스토리툴바