next.js 如何使组件在页面之间一致?

g2ieeal7  于 2022-11-23  发布在  其他
关注(0)|答案(2)|浏览(156)

当你从索引页面转到about页面时,RestOfTheApp会重新呈现。也许SSR应该这样,但是Nextjs像gatsby一样添加了静态呈现。有没有办法阻止组件重新呈现?比如:页眉不应在页面之间更改。
about.js

function index() {
  return (
    <>
        <RestOfTheApp> 
          about
        </RestOfTheApp>
    </>
  )
}

index.js

function index() {
      return (
        <>
        <RestOfTheApp> 
          index
        </RestOfTheApp>
        </>
      )
    }

我想你可以用redux保持组件状态,但是当你只需要获取一些博客内容时,整个页面的重新渲染似乎有点臃肿。我用一些基本的布局进行了测试,它看起来仍然很快,但不是整个页面的重新渲染是SPA的主要概念,我有点心碎💔

sgtfey8w

sgtfey8w1#

你在页面中包含的每个组件(在/pages下)无论你做什么都将重新呈现。但是绝对有可能添加一个在NextJs中不重新呈现的持久化布局。解决方案是自定义应用组件。你可以阅读更多关于它的内容here
以下示例有助于了解如何创建持久布局:

// /pages/_app.js

import React from 'react';
import App from 'next/app';
import Layout from '../components/Layout';

class MyApp extends App {
  render() {
    const { Component, pageProps } = this.props

    return (
      <Layout>
        <Component {...pageProps}></Component>
      </Layout>
    )
  }
}

export default MyApp

在这种情况下,当您在页面之间导航时,Layout组件将不会重新呈现.

wydwbb8l

wydwbb8l2#

@Ankit已经给出了一个关于如何创建持久化组件的很好的答案。下面是它工作的原因。
所以当你从A页导航到(在pages/a.js中定义)到另一页B(在pages/b.js中定义)首先,导航发生在客户端,这意味着不是从服务器获取呈现的HTML,在浏览器中运行一些JavaScript来呈现新页面。(您可以通过here来验证它。)页面导航的JavaScript逻辑可以归结为:
1.如果还没有预取新页面组件<B />的JavaScript代码,则从服务器获取它;

  1. Next.js将使用2个参数调用ReactDOM.render():第一个是要呈现的新React元素(可以大致认为是更新后的App组件),第二个是新React元素要呈现到的DOM容器元素(始终是<div id="__next"></div>)。
    简而言之,这个过程可以大致看作是将更新后的App组件呈现到<div id="__next"></div> DOM容器元素中,然后React将负责区分新旧React元素,并决定重新呈现DOM的哪一部分,更新哪一部分。
    那么,新的和旧的React元素看起来像什么呢?App组件的默认定义看起来像这样:
import '../styles/globals.css'

function MyApp({ Component, pageProps }) {
  // Component will be set to the current page component
  return <Component {...pageProps} />
}

export default MyApp

其中Component变量将被设置为当前页面组件。这意味着旧的React元素将如下所示:

<A {...pageProps} />

新的React元素将如下所示:

<B {...pageProps} />

根据React diffing algorithm,当比较新旧React元素时,如果被比较的两个元素是不同类型的,则相应的子树将被完全破坏并重新呈现。
<A /><B />是两个不同的组件,被认为是不同的类型,因此对应于<A />的DOM部分将被破坏并重新呈现为<B />
这就是为什么当您导航到新页面时,整个页面组件都将重新呈现,即使它们包括像header这样的公共组件。
如果你把header放在自定义的App组件中,就像这样:

import Header from '../components/header'

function MyApp({ Component, pageProps }) {
  return (
    <div>
      <Header />
      <Component {...pageProps} />
    </div>
  )
}

export default MyApp

然后,<Header />组件将在页面导航中保持不变,因为React比较算法会将其视为同一类型,并且只对子树进行最少的更新。

相关问题