NextJS, _app, SSG, getInitialProps против getStaticProps и как я должен придерживаться DRY?

Я знаю, что эта тема не нова, и я нашел (и прочитал) несколько дискуссий. Чего я не смог найти, так это ответа на мой все еще оставшийся вопрос.

Как другие решают проблему невозможности использования getStaticProps в _app.js? getInitialProps для меня не вариант, потому что я хочу использовать SSG. Есть ли способ заставить SSG даже при использовании getInitialProps? Или мне действительно нужно получать все свои данные с моей Headless CMS на каждой странице? Так как я хочу создать, например, верхний колонтитул (включая навигацию) и нижний колонтитул. В настоящее время я вижу единственный вариант - повторять много кода.

Любые подсказки очень ценятся и спасибо за чтение!

4 ответа

Next.js рекомендует использовать getStaticProps или getServerSideProps вместо getInitialProps, чтобы получить максимальную производительность от Next.js.

Если вы используете Next.js 9.3 или новее, мы рекомендуем вам использовать getStaticProps или getServerSideProps вместо getInitialProps .

Причина, по которой Next.js рекомендует это, заключается в том, что getInitialProps отключает автоматическую статическую оптимизацию и использует рендеринг на стороне сервера .

Использование getInitialProps в вашем _app.js отключит автоматическую статическую оптимизацию для всех страниц в вашем приложении. Кроме того, он заставит все ваши страницы генерироваться при каждом запросе, поскольку они используют рендеринг на стороне сервера, что приведет к плохому времени до первого байта (TTFB).

Я сделал шпаргалку по рендерингу страницы Next.js с живой демонстрацией и примерами кода на Github, чтобы быстро понять, как это работает. Это поможет вам выбрать правильную стратегию рендеринга страницы с Next.js в зависимости от вашего варианта использования.

Есть ли способ заставить SSG даже при использовании getInitialProps

Нет. Хотя команда Nextjs работает над добавлением поддержки для getStaticProps for, в настоящее время он отключает статические оптимизации.

Как рекомендует nextjs, вам следует использовать getStaticProps, когда «данные поступают из автономной CMS».

Таким образом, вам придется использовать одну и ту же логику на каждой странице, которая нуждается в запросе. Обратите внимание, что можно извлечь эту логику в функцию и повторно использовать ее повсюду.

getData.js

      export async function getData({ req, res }) {
  const data = await getData();

  return { props: { data: data} };
}

pages/example.js

      export const getStaticProps = getData

В качестве другого варианта вы можете получить данные один раз в getInitialProps.

Легко настроить (но помните, что вы потеряете статическую оптимизацию).

_app.js

      App.getInitialProps = ({ req, res }) => {
  const data = await getData();

  return { props: { data: data} };
}

Я нашел способ обойти это, используя getServerSideProps и установив заголовок Cache-Control в документе getServerSideProps .

Да. Единственный способ создания меню в SSG - получать его на каждой странице.

В случае с SSG вы должны смоделировать это в своей автономной CMS, чтобы получить все данные макета (заголовок, нижний колонтитул и любые общие данные) в одном запросе. Затем вы создаете getLayout Для запроса в getStaticProps а также Layout компонент, чтобы обернуть страницу и передать опору данных.

      function SinglePage({ layoutData }) {
  return (
    <Layout doc={layoutData}>
      
    </Layout>
  )
}

export async function getStaticProps(context){
  
  const layoutData = await getLayout() // fetch data in every single page
  
  
  return {
    props: {layoutData: layoutData || null }, 
  }
}

Макет может быть примерно таким:

      import Navbar from "@components/Navbar";
import Footer from "@components/Footer";



const Layout = ({ children, doc }) => {
  return (
    <main>
      <div className="page">
        <Navbar doc={doc.menu} />
        <div className="page-body ">{children}</div>
        <Footer doc={doc.footer}}/>
      </div>
    </main>
  );
};

export default Layout;
Другие вопросы по тегам