Giả sử ứng dụng hiện đang có các route sau:
<Route path="/" element={<Home />} />
<Route path="/books" element={<BookList />} />Dynamic Routes
Trong trường hợp ta muốn thiết lập route cho từng quyển sách, chẳng hạn như /books/1 hay /books/2, ta cần dùng dynamic route như sau:
<Route path="/books/:id" element={<Book />} />Với component Book có dạng như sau:
function Book() {
return <h1>Book</h1>
}Bất kỳ đường dẫn nào có dạng /books/:id, với :id là chuỗi ký tự bất kỳ, đều sẽ match với route trên.
Info
Trong trường hợp ta định nghĩa một route với đường dẫn được gán cứng, chẳng hạn
/books/newthì React Router sẽ không match đường dẫn này với route/books/:id.
Để lấy giá trị 1 hay 2 từ đường dẫn và hiển thị nó ở trong từng component Book, ta cần dùng hook useParams của React Router như sau:
import { useParams } from "react-router-dom"
function Book() {
const { id } = useParams()
return <h1>Book {id}</h1>
}Nested Routes
Giả sử ta có các route sau:
<Route path="/books" element={<BookList />} />
<Route path="/books/:id" element={<Book />} />
<Route path="/books/new" element={<NewBook />} />Chúng ta có thể dùng các route lồng nhau như sau:
<Route path="/books">
<Route path=":id" element={<Book />} />
<Route path="new" element={<NewBook />} />
</Route>Để render ra component BookList tương ứng với đường dẫn /books, ta cần thêm vào một route có props index như sau:
<Route path="/books">
<Route index element={<BookList />} />
<Route path=":id" element={<Book />} />
<Route path="new" element={<NewBook />} />
</Route>Layout
Giả sử ta có các liên kết đến các route của /books như sau:
<ul>
<li>
<Link to="/books/1">Book 1</Link>
</li>
<li>
<Link to="/books/2">Book 2</Link>
</li>
<li>
<Link to="/books/new">New Book</Link>
</li>
</ul>Để thêm các liên kết này vào các component thuộc các route của /books, ta có thể cho chúng vào một layout component, chẳng hạn BookLayout:
import { Link, Outlet } from "react-router-dom"
function BookLayout() {
return (
<>
<ul>
<li>
<Link to="/books/1">Book 1</Link>
</li>
<li>
<Link to="/books/2">Book 2</Link>
</li>
<li>
<Link to="/books/new">New Book</Link>
</li>
</ul>
<Outlet />
</>
)
}Important
Lưu ý là ta cần phải gọi component
Outletđể chỉ định vị trí mà child route được render.
Sau đó gọi sử dụng layout này ở route /books:
<Route path="/books" element={<BookLayout />}>
<Route index element={<BookList />} />
<Route path=":id" element={<Book />} />
<Route path="new" element={<NewBook />} />
</Route>Bằng cách này, các child route của /books sẽ luôn có một danh sách các liên kết đi kèm.
Context
Ở trong component Outlet, ta có thể truyền dữ liệu cho các child route thông qua một props có tên là context như sau:
<Outlet context={{ saleOff: 50 }}Lấy ra context ở trong các component thuộc các child route bằng cách dùng hook useOutletContext như sau:
import { useOutletContext } from "react"
function Book() {
const context = useOutletContext()
return (
<h1>
Book {id} (Sale off: {context.saleOff}%)
</h1>
)
}Routes Component
Ta có thể tách các route thành một component riêng:
function BookRoutes() {
return (
<Routes>
<Route element={<BookLayout />}>
<Route index element={<BookList />} />
<Route path=":id" element={<Book />} />
<Route path="new" element={<NewBook />} />
</Route>
</Routes>
)
}Và dùng component đó ở route /books như sau:
<Route path="/books/*" element={<BookRoutes />} />Lưu ý là ta cần thêm vào path chuỗi /*.
useRoutes
Thay vì dùng component Routes và Route để thiết lập các route của ứng dụng, ta có thể sử dụng hook useRoutes như sau:
const Routes = useRoutes([
{
path: "/",
element: <Home />,
},
{
path: "/books/*",
element: <BookRoutes />,
},
{
path: "*",
element: <NotFound />,
},
])Gọi sử dụng như là một JSX element:
function App() {
return (
// ...
{ Routes }
)
}