#reactjs #next.js
#reactjs #next.js
Вопрос:
У меня есть простой компонент React:
const Page = ({ data }) => {
return (
<header>
{data.length !== 0 ?
<>
{data((d) =>
// render data
)}
</>
:
<>Loading...</>
}
</header>
)
}
Я получаю данные с помощью Next.js рекомендуемый getServerSideProps
:
export async function getServerSideProps() {
// Fetch data from external API
const res = await fetch(`someurl`)
const data = await res.json()
// Pass data to the page via props
return { props: { data } }
}
Теперь, ради всего святого, я не могу понять, почему <>Loading...</>
никогда не выполняется рендеринг. Страница пуста, а затем все появляется. Почему это происходит и как мне это исправить? конечно, data.length РАВЕН 0, прежде чем он будет извлечен…
Обратите внимание, что я использую динамическую маршрутизацию и не хочу использовать getStaticProps
.
Ответ №1:
getServerSideProps
всегда выполняется на стороне сервера также для навигации на стороне клиента.
Когда вы возвращаетесь data
из getServerSideProps
(если fetch
метод выполняется без ошибок), он всегда будет возвращать значение.
В вашем примере <Loading />
будут видны только в том случае, если данные, возвращаемые из fetch
, имеют длину 0 и никогда не будут видны во fetch
время.
Здесь документы https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering
Комментарии:
1. Я новичок в Next.js и это действительно сбивает с толку. Где в документации говорится, что используемый компонент
getServerSideProps
будет отсутствовать до получения данных? Что я должен использовать для динамического контента, например. доска с сообщениями? Только getInitialProps? Они говорят, что это бесполезно, и это отключаетAutomatic Static Optimization
:/ Я хочу что-то предварительно отобразить, а затем передать ему данные API, прежде чем он загрузится, я хочу увидеть «загрузка …»2.
getServerSideProps
при выполнении генерируйте JSON, который будет введен в компонент страницы. Таким образом, он не генерирует статический код, но генерирует статические данные во время выполнения, я думаю, это лучший выбор для предварительной загрузки динамических данных на стороне сервера.getInitialProps
Не рекомендуется использовать.3. Я понимаю, но что мне теперь делать? Я пробовал
getInitialProps
, хотя это не рекомендуется, и это работает точно так же — я нажимаю на ссылку, ничего не происходит в течение 30 секунд, затем baam, все загружается, и с этого момента все работает. Я хочу нажать на ссылку и иметь «loading …» при извлечении данных. Данные будут динамическими. Как мне добиться этого с помощью Next.js ?4. Просто
fetch
передайте данные на стороне клиента и установите состояние загрузки. Удалите обаgetServerSideProps
иgetInitialProps
. Вы также можете использоватьswr
библиотеку swr.vercel.app , которая предоставляет множество функций для извлечения данных.5. Конечно, если вы используете
swr
, вы можете передать некоторыеinitialData
данные, поступающие с server. swr.vercel.app/docs/с помощью-nextjs . (пример ссылки приведен сgetStaticProps
помощью , но вы можете свободно использоватьgetServerSideProps
).
Ответ №2:
Очевидно, что пользователь не должен ждать несколько секунд, в течение которых ничего не происходит (потому что загрузка getServerSideProps не завершена), когда он нажимает на ссылку. Он должен видеть, что происходит какое-то действие, например:
- Загрузка счетчика
- Шаблон данных (поля для изображений, текста и так далее), пример youtube.
Но на данный момент это невозможно с getServerSideProps, потому что страница отображается только после завершения запроса getServerSideProps.
Существует будущий запрос на next.js об этом, поэтому я надеюсь, что это будет реализовано.
Ответ №3:
вам необходимо использовать метод isFallback, предоставляемый следующим / маршрутизатором. посмотрите на этот код, попробуйте найти isfallback https://github.com/vercel/next-site/blob/master/pages/docs/[[…slug]].js .
Edit:
`export async function getServerSideProps() {
Fetch data from external API
const res = await fetch(someurl)
const data = await res.json()
Pass data to the page via props
return {
props: res ? {
data,
id,
url,
} : {}
};
}
`
and in your component
const router = useRouter();
const { isFallback } = router
if (isFallback) {
return <Loading />
}
else {
return (
// render data
)
}
Комментарии:
1. Это то, чего я не понимаю, когда я нажимаю на ссылку, перенаправление происходит только после получения данных. Таким образом, isFallback никогда не включается, так как страница загружается только тогда, когда она готова:/ Даже когда я набираю ее вручную, например localhost:3000/foo / bar, ничего нет (белый экран), а затем бам, все загружено.
2. вы используете рендеринг на стороне сервера в nextjs. ваши данные извлекаются только один раз, а затем при следующем посещении вам будет предоставлена статическая html-страница. Поэтому, когда ваша страница загружается в первый раз, isFallback будет иметь значение true, когда ваши данные извлекаются, isFallback станет false. на основе isFallback вы можете показать некоторый скелет, и когда ваши данные будут извлечены, делайте то, что хотите, я тоже обновил свой ответ. посмотрите на это
3. Не совсем, я понимаю вашу точку зрения, но при первом рендеринге ничего не
isFallback
загружается, а затем сразу отображается вся страница с загруженными данными. Перед ним просто белый экран, даже если загрузка занимает более минуты. Ничего не отображается.4. Резервный вариант @Wordpressor предназначен для getStaticProps, а не для getServerSideProps.