理解Next.js中的_app.js和_document.js文件

摘要:在Next.js项目中,你会在pages文件夹里看到两个特殊的文件:_app.js和_document.js。它们各自承担着不同的重要任务,正确使用这两个文件能让你的应用更加稳定和高效。

在Next.js项目中,你会在pages文件夹里看到两个特殊的文件:_app.js和_document.js。它们各自承担着不同的重要任务,正确使用这两个文件能让你的应用更加稳定和高效。


什么是_app.js?

可以把_app.js看作整个Next.js应用的"总管家"。它包裹着所有的页面组件,为它们提供统一的环境和配置。

当用户在页面间跳转时,Next.js会卸载旧的页面组件,加载新的页面组件,但_app.js组件始终保持不变。这个特性让它特别适合管理全局状态和布局。


app.js的主要作用

保持页面状态
由于_app.js不会在页面切换时重新创建,你可以在这里放置全局状态管理。比如使用React Context或Redux Provider,这样用户在页面间跳转时,登录状态、主题设置等数据就不会丢失。

引入全局样式
这是官方推荐的全局样式引入位置。你可以在这里导入CSS文件或配置CSS-in-JS库,确保所有页面都能应用统一的样式。

设置统一布局
你可以用布局组件包裹页面内容,这样每个页面都会自动采用相同的布局结构,不需要在每个页面文件中重复编写布局代码。

传递全局数据
可以在这里获取用户认证信息等全局数据,然后通过pageProps传递给每个页面组件。

错误处理
通过实现componentDidCatch生命周期方法,可以捕获和处理整个应用中的JavaScript错误。


app.js的基本结构

_app.js接收两个重要的props:

Component:当前要渲染的页面组件

pageProps:页面组件需要的props数据

// pages/_app.js
import '@/styles/globals.css'
import Layout from '@/components/Layout'

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

export default MyApp


什么情况下使用_app.js?

需要统一的页面布局时

要使用全局状态管理时

要引入全局CSS样式时

需要在所有页面间保持某些状态时


什么是_document.js?

_document.js文件主要负责定制HTML文档的结构。它只在服务端运行,用于修改最终输出的HTML模板。

需要注意的是,_document.js在浏览器端不会执行,所以你不能在这里使用React的生命周期方法或事件处理。


document.js的主要作用

修改HTML结构
你可以给html、body标签添加属性,比如设置语言类型或添加CSS类名。

添加head内容
虽然可以在页面中使用Next.js的Head组件,但_document.js中的Head用于添加那些必须在首次加载时就存在的标签,比如字体链接、关键meta标签等。

支持CSS-in-JS服务端渲染
对于styled-components这样的CSS-in-JS库,需要在_document.js中配置服务端渲染,确保样式不会闪烁。


document.js的基本结构

_document.js必须包含四个核心组件:Html、Head、Main和NextScript。

// pages/_document.js
import { Html, Head, Main, NextScript } from 'next/document'

export default function Document() {
  return (
    <Html lang="zh-CN">
      <Head>
        <link
          href="https://fonts.googleapis.com/css2?family=Inter&display=swap"
          rel="stylesheet"
        />
        <meta name="description" content="网站描述信息" />
      </Head>
      <body className="custom-body-class">
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}


什么情况下使用_document.js?

需要修改html或body标签的属性时

要添加自定义字体或关键meta标签时

需要配置CSS-in-JS库的服务端渲染时


两个文件的区别

特性_app.js_document.js
运行环境服务端和客户端仅服务端
主要作用管理页面逻辑和状态定制HTML文档结构
可用功能可以使用所有React特性不能使用React生命周期和事件
修改目标页面内容和布局HTML文档标签

实际使用建议

从简单开始
刚开始使用Next.js时,你可能不需要立即创建这两个文件。Next.js会提供默认版本,等有具体需求时再创建自定义版本。

注意执行环境
记住_document.js只在服务端运行,不要在这里写客户端代码。_app.js则在服务端和客户端都会执行。

合理分工
与页面显示相关的内容放在_app.js,与HTML文档结构相关的内容放在_document.js。

保持简洁
不要在_document.js中添加大量逻辑,它应该尽量保持简单和稳定。


常见问题解答

问:可以在_document.js中使用useState吗?
答:不可以。_document.js只在服务端运行,不能使用React的hooks。

问:两个文件都需要手动创建吗?
答:不是。Next.js会自动使用默认版本,当你需要自定义行为时才需要创建它们。

问:哪个文件先执行?
答:_document.js先执行,它生成基本的HTML框架,然后_app.js在其中渲染React组件。

问:可以在_app.js中修改HTML标签吗?
答:不可以。修改HTML标签是_document.js的职责。

通过合理使用这两个文件,你可以更好地控制Next.js应用的行为和表现。记住它们的分工:_app.js管内容,_document.js管结构。掌握这个原则,你就能更自如地构建Next.js应用了。

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://shenqiku.cn/article/FLY_13147