Вы должны использовать здесь динамические c маршруты, если хотите работать с такими методами выборки данных, как getStaticProps
или getServerSideProps
.
Вы можете создать страницу типа pages/book/[id].js
. Но чтобы сгенерировать страницу, вы должны решить, какой метод выборки данных вы хотите запустить. Если данные для страницы меняются не очень часто, вы можете использовать stati c -site-generation, используя getStaticProps
, который будет генерировать страницы во время сборки. Если данные будут сильно меняться, вы можете выполнить рендеринг на стороне сервера, используя getServerSideProps
, или получить данные на стороне клиента.
Вот пример вашего варианта использования, который вы можете использовать для сервера -side-рендеринг с использованием getServerSideProps
, имейте в виду, что вызов API внутри getServerSideProps
может завершиться ошибкой, поэтому у вас должна быть соответствующая обработка ошибок.
In pages/book/[id].js
import axios from 'axios';
import BookAttributes from '../components/Book/BookAttributes';
export const getServerSideProps = async (ctx) => {
const bookId = ctx.params?.id
const url = 'http://localhost:3000/api/book';
const response = await axios.get(url, { params: { _id: bookId} })
return {
props: {
book: response.data
}
}
}
function Book({ book }) {
return (
<>
<h1>Book Page</h1>
<BookAttributes {...book} />
</>
)
}
export default Book;
Использование stati c -site-generation Поскольку страница является динамической c, вы должны предоставить список путей, для которых следующая js будет генерировать страницы. Это можно сделать, экспортировав функцию asyn c с именем getStaticPaths
.
в pages/book/[id].js
import axios from 'axios';
import BookAttributes from '../components/Book/BookAttributes';
export const getStaticPaths = async () => {
// here you have two options if you know all the ids of the books
// you can fetch that data from the api and use all the ids to generate
// a list of paths or show a fallback version of page if you don't know all
// ids and still want the page to be static
// Pseudo code might look like this
const res = await axios.get('api-endpoint-to-fetch-all-the-books')
const paths = res.data.map(book => ({ params: { id: book.id }}))
return {
paths,
fallback: false
}
}
export const getStaticProps = async (ctx) => {
const bookId = ctx.params?.id
const url = 'http://localhost:3000/api/book';
const response = await axios.get(url, { params: { _id: bookId} })
return {
props: {
book: response.data
}
}
}
function Book({ book }) {
return (
<>
<h1>Book Page</h1>
<BookAttributes {...book} />
</>
)
}
export default Book;
Свойство fallback
в возвращаемом значении getStaticPaths
равно несколько важно понять. Если вы знаете все необходимые id
для страниц, вы можете установить fallback
на false
. В этом случае следующий js просто покажет страницу ошибки 404
для всех путей, которые не были возвращены функцией getStaticPaths
.
Если fallback
установлен на true
следующий js будет отображать резервную версию страницы вместо страницы 404
для путей, которые не были возвращены функцией getStaticPaths
. Где теперь установить fallback
в значение true? Предположим, что в вашем случае новые книги добавляются в базу данных часто, но данные о книгах меняются не очень часто, поэтому вы хотите, чтобы страницы были статичными c. В этом случае вы можете установить fallback
на true
и создать список путей на основе доступных идентификаторов книг. Для новых книг следующий js сначала покажет резервную версию страницы, затем получит данные на основе идентификатора, указанного в запросе, и отправит данные как JSON, которые будут использоваться для визуализации страницы в клиенте.