Component-level static props in Next.js

栏目: IT技术 · 发布时间: 4年前

内容简介:One of Next.js' most useful features is that itTo help simplify pre-rendering, Next.js requires that dynamic data is prepared at the page-level. Components inside a page can't define their ownThe flow of props in a statically rendered Next.js page.

One of Next.js' most useful features is that it pre-renders apps. By executing our code before React renders in the browser, Next.js produces static HTML documents that can be cached by CDNs and displayed without any client-side JavaScript running.

To help simplify pre-rendering, Next.js requires that dynamic data is prepared at the page-level. Components inside a page can't define their own static props or server side props . They can of course be dynamic , but Next.js will pre-render them in their initial state. Usually we pass the props prepared during pre-render down the tree to the components that need them.

┌──────────────────────┐        ╔════════════╗
│                      │        ║            ║
│   getStaticProps()   │───────▶║  <Page />  ║
│                      │        ║            ║
└──────────────────────┘        ╚════════════╝
                                       │
                         ┌─────────────┴───────────┐
                         ▼                         ▼
                ┌─────────────────┐       ┌─────────────────┐
                │                 │       │                 │
                │  <Component />  │       │  <Component />  │
                │                 │       │                 │
                └─────────────────┘       └─────────────────┘
                                                   │
                                          ┌────────┘
                                          ▼
                                 ┌─────────────────┐
                                 │                 │
                                 │  <Component />  │
                                 │                 │
                                 └─────────────────┘

The flow of props in a statically rendered Next.js page.

This pattern works great, but wouldn't it be neat if we could add static props from individual components? Think about static queries in Gatsby. They can be dropped into the component tree at any level to fetch data. The page itself doesn't need to be aware of all the data required by the components within.

Shu, a developer at Vercel, shows us that this can be achieved with Next.js. The Next-CMS project provides a <CMS /> component that can be used to fetch and statically insert data from WordPress in any component.

Next-CMS uses Next.js' Static Site Generation (SSG) via the getStaticProps function, and that is what we will focus on in this post.

Static sites are a great option for displaying content from a CMS, because it's usually unnecessary to fetch fresh data for every request. Next.js' Incremental Static Regeneration (ISR) feature allows static pages to be regenerated in the background, so we don't have to worry about stale content. This is kind of a superpower when compared to Gatsby's build model!

The <CMS /> component accepts an endpoint prop to define its data source, and the fetched data is passed into a child render function. The assigned endpoint is automatically lifted up to the page's getStaticProps function and fetched when the page is pre-rendered.

const Header = () => (
  <CMS endpoint='/wp-json'>
    {data => (
      <div>
        <h1>{data.name}</h1>
        <p>{data.description}</p>
      </div>
    )}
  </CMS>
)

In this example from the Next-CMS docs, the <Header /> component will be pre-rendered using the site data retrieved from WordPress. The data is fetched only at pre-render—never on the client—and rendered to static HTML. We benefit from all the advantages of getStaticProps , because indirectly that's what we are using.

The inner workings of Next-CMS

Next-CMS doesn't add any special capabilities to Next.js. Instead, it cleverly uses double rendering to automatically lift the requested endpoints up to the page's getStaticProps function. The fetched data then gets injected at render time using React Context.

There are three parts to this technique.

1. Lifting and resolving API requests

A function is provided that gathers and fetches the endpoints assigned to nested <CMS /> components. It's called from inside the getStaticProps function, and uses ReactDOM's renderToStaticMarkup to perform an extra page render prior to Next.js' pre-render.

During this extra render, the endpoints of all nested <CMS /> components are pushed to a global array . They are added to a Set —which is a convenient way to deduplicate them—and then resolved in parallel using fetch .

   ┌─────────────────────────────────────┐        ╔════════════╗
   │          getStaticProps()           │        ║            ║
┌─▶│                                     │───────▶║  <Page />  ║
│  │   global.__next_ssg_requests = []   │        ║            ║
│  └─────────────────────────────────────┘        ╚════════════╝
│                     ▲                                  │
│                     │        ┌─────────────────────────┴──────────────┐
│  ┌──────────────────┘        ▼                                        ▼
│  │  ┌─────────────────────────────────────────────────┐      ┌─────────────────┐
│  │  │           <CMS endpoint='/wp-json' />           │      │                 │
│  └──│                                                 │      │  <Component />  │
│     │   global.__next_ssg_requests.push('/wp-json')   │      │                 │
│     └─────────────────────────────────────────────────┘      └─────────────────┘
│                                                                       │
│                                                  ┌────────────────────┘
│                                                  ▼
│                   ┌─────────────────────────────────────────────────────────────┐
│                   │           <CMS endpoint='/wp-json/wp/v2/posts' />           │
└───────────────────│                                                             │
                    │   global.__next_ssg_requests.push('/wp-json/wp/v2/posts')   │
                    └─────────────────────────────────────────────────────────────┘

Gathering static props before pre-render. Each CMS component pushes its assigned endpoint to a global array. Once the required endpoints have been lifted up to the getStaticProps function, they are fetched in parallel. The fetched data is passed into the page props when Next.js pre-renders the page.

The fetched data is added to an object , where its key is the requested endpoint. This object is passed into the page props . Because the key is the requested endpoint, it can be mapped back to the relevant <CMS /> component when the page is rendered.

2. React Context

The withCMSPage higher order component wraps the page in a React Context . The Context is initialised using the fetched data from the page props. <CMS /> components nested at any level can then read the data returned from their assigned endpoint.

                          ┌──────────────────────┐        ╔════════════╗
                          │                      │        ║            ║
                          │   getStaticProps()   │───────▶║  <Page />  ║
                          │                      │        ║            ║
                          └──────────────────────┘        ╚════════════╝
                                                                 │
                                                                 │
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━│━━━━━━━━━━━━━━━━━┓
┃                                                                │                 ┃
┃ <CMSContext.Provider value={props.__next_ssg_data || {}} />    ├─────┐           ┃
┃                                                                │     │           ┃
┃                                                                │     │           ┃
┃                              ┌─────────────────────────────────┘     │           ┃
┃                              │                                       │           ┃
┃                              ▼                                       ▼           ┃
┃           ┌─────────────────────────────────────┐           ┌─────────────────┐  ┃
┃           │     <CMS endpoint='/wp-json' />     │           │                 │  ┃
┃           │                                     │           │  <Component />  │  ┃
┃           │  const data = context['/wp-json']   │           │                 │  ┃
┃           └─────────────────────────────────────┘           └─────────────────┘  ┃
┃                                                                      │           ┃
┃                                                 ┌────────────────────┘           ┃
┃                                                 ▼                                ┃
┃                  ┌─────────────────────────────────────────────────────────────┐ ┃
┃                  │           <CMS endpoint='/wp-json/wp/v2/posts' />           │ ┃
┃                  │                                                             │ ┃
┃                  │        const data = context['/wp-json/wp/v2/posts']         │ ┃
┃                  └─────────────────────────────────────────────────────────────┘ ┃
┃                                                                                  ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

The fetched data is injected into the CMS components using React Context.

3. The CMS component

The <CMS /> component runs in two different modes.

During the extra render, it simply pushes its assigned endpoint to a global array . It doesn't render any UI, because the extra render is performed only to lift required endpoints up to the getStaticProps function.

During a normal render, the <CMS /> component reads the fetched data from Context, and then passes it down to its child render function .

There's a few connected parts to think about here. The important thing is that it's relatively simple for users to set up. The withCMSPage and getCMSStaticProps function are all we need to add to start using the <CMS /> component.

The inner workings are useful to understand if you want to apply this technique yourself. It's an interesting way to assemble a page because, beyond data fetching, it can be used to move work from the client render stage to the pre-render stage.

This website, for example, transforms code blocks to static HTML during pre-render, meaning the browser doesn't have to download and run a highlighter such as Prism.js. Manually adding every code block to getStaticProps would be very cumbersome, but automatically lifting the code blocks up to getStaticProps makes it convenient. (More about static code block rendering soon!)

I can see this pattern being really useful in Next.js apps, but it is a little fiddly. A small wrapper library could help solve that, or it could even be incorporated into Next.js itself.


以上所述就是小编给大家介绍的《Component-level static props in Next.js》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

代码大全(第2版)

代码大全(第2版)

[美] 史蒂夫·迈克康奈尔 / 金戈、汤凌、陈硕、张菲 译、裘宗燕 审校 / 电子工业出版社 / 2006-3 / 128.00元

第2版的《代码大全》是著名IT畅销书作者史蒂夫·迈克康奈尔11年前的经典著作的全新演绎:第2版不是第一版的简单修订增补,而是完全进行了重写;增加了很多与时俱进的内容。这也是一本完整的软件构建手册,涵盖了软件构建过程中的所有细节。它从软件质量和编程思想等方面论述了软件构建的各个问题,并详细论述了紧跟潮流的新技术、高屋建瓴的观点、通用的概念,还含有丰富而典型的程序示例。这本书中所论述的技术不仅填补了初......一起来看看 《代码大全(第2版)》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具