我建议将
Layout
组件更新为路由布局组件,为它渲染的嵌套路由渲染 Outlet
,然后在出口上下文上提供 books
数组以供嵌套路由使用。这允许更深层嵌套的路由通过 bookId
路由路径参数获取特定书籍的详细信息。
import { Outlet } from 'react-router-dom';
export const BooksLayout = () => {
...any business logic the layout had
return (
<>
...any common UI the layout had
{/* Render Outlet for nested routes and provide books array */}
<Outlet context={{ books }} />
...any common UI the layout had
</>
);
};
<Routes >
<Route path="/" element={<Navigate to="/login" replace />} />
<Route path="/login" element={<Login />} />
<Route element={<BooksLayout />}>
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/sale/:bookId">
<Route index element={<BookDetails />} /> // "/sale/:bookId"
<Route path="salebooks" element={<SaleBooks />} /> // "/sale/:bookId/salebooks"
<Route path="viewbooks" element={<ViewBooks />} /> // "/sale/:bookId/viewbooks"
</Route>
</Route>
<Route path="*" element={<NotFound />} />
</Routes>
useOutletContext
钩子来访问插座上下文提供者提供的 books
数组。
仪表板
import { Link, useOutletContext } from 'react-router-dom';
...
const { books } = useOutletContext();
...
{books.map((book) => (
<div className="col" key={book.id}>
<div className="card h-100">
<div className="card-img-top pb-5 mb-5">
</div>
<div className="card-body">
<Link to={`/sale/${book.id}`}>
<button
type="submit"
className="btn custome-btn purple-active-ghost w-100"
>
{book.title}
</button>
</Link>
</div>
</div>
)}
书籍详情
import { Link, useOutletContext, useParams } from 'react-router-dom';
...
const { bookId } = useParams();
const { books } = useOutletContext();
const book = books.find(book => book.id === bookId);
...
// if book exists, access all book object properties, e.g. id, title, and more
<Link to={`/sale/${book.id}/salebooks`}>
<button
type="submit"
className="btn custome-btn purple-active-ghost w-100"
>
go to {book.title} salebooks
</button>
</Link>