Предварительная загрузка данных getServerSideProps с помощью Next.js ?

#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.