Я создаю библиотечный сервис, используя в основном react
, redux-toolkit
и react-router
.
Я хотел бы добавить динамический маршрут, который представляет собой страницу, на которой отображаются сведения о выбранной книге. Этот маршрут должен быть доступен с домашней страницы, где у меня есть несколько изображений обложек книг, и со страницы каталога, где показан весь список. Я совсем запутался в этом.
navigate
перейти к /catalogue/:bookId
с главной страницы и страницы каталога, но не отображается правильный компонент. Я думаю, что неправильно понял смысл детей внутри объекта маршрута, есть предложения? Должен ли я использовать <Outlet />
и какой поток для этого правильный?Часть router.tsx
{
path: '/',
element: <Home />,
},
{
path: 'catalogue',
element: <Catalogue />,
children: [
{
path: '/catalogue/:bookId',
element: <BookDetails />
}
]
},
Часть компонента <Catalogue />
, в котором я визуализирую для каждой книги в списке.
{
list.map((book, i) => {
return (
<BookCard
book = {book}
key = {`book-${i}`} />
)
})
}
<BookCard />
компонент
const BookCard = ({ book }: {
book: IBook;
}) => {
const dispatch = useAppDispatch();
const navigate = useNavigate();
const handleClick = () => {
dispatch(exploredBook(book));
navigate(`/catalogue/${book.id}`)
}
return (
<Col>
<Card className = "book-card">
<Row>
<Col>
<Card.Img
className = "book-img"
variant = "top"
src = {book.imageLink}
alt = {`${book.title} book cover`} />
</Col>
<Col>
<Card.Body>
<Card.Title as = {Link} to = {`/catalogue/${book.id}`}>{book.title}</Card.Title>
<Card.Subtitle>{book.author}, {book.year}</Card.Subtitle>
{
book.book_status.copies <= 0
? <Badge bg = "danger">Out of stock</Badge>
: <Badge bg = "success">{book.book_status.copies} copies available</Badge>
}
<CatalogueActions book = {book} />
<Card.Link href = {book.link} target='_blank'>
<small>More about <em>{book.title}</em> on Wikipedia</small>
</Card.Link>
</Card.Body>
</Col>
</Row>
</Card>
</Col>
)
};
export default BookCard;
/localhost:3000/catalogue/o23ifo2eifj8249g2g24g
. Но если пользователь напишет вручную URL-адрес и вставит случайный идентификатор, страница все равно отобразит содержимое. Как я могу предотвратить рендеринг контента? Моим простым решением было бы выполнить поиск в database
, используя хук useParams()
для письменного идентификатора: если существует, отображается соответствующая книга, если не существует, отображается страница 404. Есть ли лучшее более простое решение?🤔 А знаете ли вы, что...
React поддерживает создание контролируемых и неконтролируемых компонентов форм.
С текущей конфигурацией маршрутов:
{
path: '/',
element: <Home />,
},
{
path: 'catalogue',
element: <Catalogue />,
children: [
{
path: '/catalogue/:bookId', // <-- or simply ":bookId"
element: <BookDetails />
}
]
},
Отрисовывается вложенный маршрут на path = "/catalogue/:bookId"
.
Должен ли я использовать
<Outlet />
и какой поток для этого правильный?
Да, в этой конфигурации компонент Catalogue
обязательно должен отображать компонент Outlet
для вложенных маршрутов, чтобы отображать их содержимое. Это случай использования, когда вы хотите отображать Catalogue
и BookDetails
одновременно.
Пример каталога:
{list.map((book, i) => {
return (
<BookCard
book = {book}
key = {`book-${i}`} />
)
})
}
...
<Outlet />
Если это не так, и вы хотите, чтобы Catalogue
и BookDetails
отображались каждый на своих независимых страницах, то маршруты должны быть невложенными.
Пример:
{
path: '/',
element: <Home />,
},
{
path: 'catalogue',
element: <Catalogue />,
},
{
path: '/catalogue/:bookId',
element: <BookDetails />
}
или
{
path: '/',
element: <Home />,
},
{
path: 'catalogue',
children: [
{
index: true,
element: <Catalogue />
},
{
path: ':bookId',
element: <BookDetails />
}
]
},
Когда пользователь доходит до деталей книга, URL-адрес должен быть примерно таким
"/catalogue/o23ifo2eifj8249g2g24g"
. Если пользователь, напишите вручную URL-адрес и вставьте случайный идентификатор, страница будет отображаться тем не менее содержание. Как я могу предотвратить рендеринг содержание? Моим простым решением было бы сделать поиск в базе данных используя хукuseParams()
для письменного идентификатора: если существует, отображается соответствующая книга, если она не существует, отображается страница 404 предоставлено. Есть ли лучшее более простое решение?
Это стандартная практика для проверки параметров пути динамического маршрута и либо перенаправления пользователя на страницу 404, либо условного отображения некоторого резервного пользовательского интерфейса на странице BookDetails
при использовании недопустимого значения bookId
.