Я ищу решения для лучшего извлечения данных в приложении Next. js. В этом вопросе я не просто ищу решение , я ищу несколько вариантов, чтобы мы могли взглянуть на плюсы и минусы.
У меня проблема
Прямо сейчас у меня есть несколько страниц, все из которых содержат компонент, отображающий содержимое som stati c, и объект, содержащий некоторое динамическое содержимое c, извлекаемое из API. Каждая страница делает fetch()
в своих getInitialProps()
, чтобы получить свои собственные данные страницы, но также и данные нижнего колонтитула, , которые одинаковы для всех страниц .
Это, конечно, работает, но есть много дублированных выборок данных. Данные нижнего колонтитула всегда будут отображаться для всех страниц и всегда будут одинаковыми. Это также редко будет изменяться в API, поэтому нет необходимости повторной проверки данных.
Ответы, которые я ищу
Я не просто ищу решение этой одной проблемы, я Я ищу обзор, чтобы узнать некоторые новые практики для будущих проектов. Мне нравится писать «очевидный» код, поэтому я не ищу слишком хакерских решений, как, например, запись в объект window
et c. Простые решения с меньшими зависимостями являются предпочтительными. Цель - быстрый сайт. Это не так важно, чтобы сократить использование сети / вызовы API.
То, что я до сих пор думал
Это возможные решения, которые я придумал, несколько от простого / очевидного до более сложный.
- Выполнение выборки внутри компонента Нижний колонтитул (на стороне клиента)
- Выполнение выборки в getInitialProps (на стороне сервера и на стороне клиента) для всех / страниц
- Выполнение получить в _app. js с HO C и подключить его к
getInitialProps()
и добавить его в реквизит, чтобы данные были доступны для всех страниц - Используйте zeit / swr и предварительную выборку данных для кэширования данных
- Использование приставки для хранения глобального состояния
Все это «работает», но большинство из них будет без необходимости перезагружать данные и / или добавляет немного больше сложности. Вот плюсы / минусы, как я вижу (цифры те же, что и выше):
- ? Просто! Получить код только в одном месте, он находится там, где он используется. ? Данные извлекаются после загрузки страницы, поэтому содержимое «скачет» для просмотра. Данные обновляются постоянно.
- ? Просто! Данные извлекаются на сервер, поэтому содержимое доступно до отображения страницы. ? Данные обновляются для каждой страницы. Мы должны помнить, чтобы извлекать одинаковые данные нижнего колонтитула для каждой страницы в их
getInitialProps()
. - ? Мы можем сделать выборку в одном месте и добавить ее ко всем опорам страниц, чтобы данные нижнего колонтитула автоматически были доступны для реквизит всех страниц. Some Для некоторых может быть немного сложнее понять, что происходит, так как для этого требуется немного больше понимания того, как работает Next.js / React. Все еще обновляет данные для всех страниц. Теперь мы делаем два
fetch()
вызова друг за другом (сначала в _app. js для загрузки содержимого нижнего колонтитула, затем на каждой странице для получения пользовательского содержимого), так что это еще медленнее. - what Довольно просто. Мы можем использовать предварительную выборку для загрузки данных в кэш даже до загрузки JS. После первой загрузки страницы у нас будет быстрый выбор данных. Может иметь код извлечения непосредственно в компоненте нижнего колонтитула. Technique Техника предварительной выборки
rel="preload"
не будет работать со всеми типами выборки (например, клиент Sanity, использующий groq). Чтобы не иметь «скачкообразного» содержимого, когда данные загружаются после начальной загрузки страницы, мы должны предоставить useSWR()
с initialData
, что все равно потребует от нас извлечения данных в getInitialProps()
, но этого будет достаточно просто сделать это на на стороне сервера. Могли бы использовать новый getServerSideProps()
. - ? Мы можем загрузить данные один раз (?) И сделать их доступными во всем приложении. Быстро и меньше / без повторной заправки. ? Добавляет внешнюю зависимость. Более сложным, так как вам придется учить лексему даже загружать один общий объект данных.
Текущее решение, использующее решение, описанное в пуле № 2.
const HomePage = (props) => {
return (
<Layout data={props.footer}>
<Home data={props.page} />
</Layout>
)
}
// Not actual query, just sample
const query = `{
"page": *[_type == "page"][0],
"footer": *[_type == "footer"][0]
}`
HomePage.getInitialProps = async () => {
const data = await client.fetch(query)
return {
page: data.page
footer: data.footer
}
}
export default HomePage
Хотелось бы еще немного разобраться в этом. Я что-то упускаю очевидное?