必会的next.js自定义App和Document

本文介绍Next.js中自定义App组件与Document组件的方法,包括如何重构App组件以实现全局状态管理、自定义错误处理及数据注入,同时探讨自定义Document以优化服务器端渲染。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

每个项目产品都要加埋点,加500行埋点是不是会占用你一两天的时间而且很容易犯错,想只用一小时准确加完这500行埋点剩下一天喝茶聊天么?来试试这520web工具, 高效加埋点,目前我们公司100号前端都在用,因为很好用,所以很自然普及开来了,推荐给大家吧

http://www.520webtool.com/

自己开发所以免费,埋点越多越能节约时间,点两下埋点就加上了,还不会犯错,里面有使用视频,反正免费 😄

原文链接:https://juejin.im/post/5cc08f0de51d453f38191d64

前言

这篇文章将介绍Next.js中自定义App组件、Document组件以及什么时候需要自定义这些内容,这可能会是我们每个项目中都要做的事情,So,让我们一起掌握它吧。

Tips: 按照惯例声明,笔者也是个入门级选手,文章深度无法达到大佬级文章水平,只希望能对各位入门级的小伙伴有所帮助。

自定义App

首先说一下为什么要自定义App,这里的App其实就是我们平时写react时候的根组件。 1)通过重写_app.js文件,我们可以对App组件进行重构,在App组件中加入一些项目中不变的内容,比如页面的布局;

2)在App中保持公用的状态,这里的公用状态也可以是一些全局的css,比如我们之前搭建环境的文章中加入的antd.css

3)以及给页面传递自定义的数据,

4)使用componentDidCatch自定义处理错误;

5)注入额外数据到页面里 (如 GraphQL 查询)

next.js+koa2+antd环境轻松搭建 一文中,我们曾经写过一个_app.js来引入antd的css,在这里我们对除了引入antd.css其他事情什么都没做,引入antd.css之后,它就会在全局生效。

 
  1. import App from 'next/app'

  2. import 'antd/dist/antd.css'

  3. export default App

  4. 复制代码

现在就来对它进行一些改变

 
  1. import App, { Container } from 'next/app'

  2. import 'antd/dist/antd.css'

  3.  
  4. // 新增了这一段

  5. class MyApp extends App {

  6. render() {

  7. const { Component } = this.props;

  8. console.log(Component);

  9.  
  10. return (

  11. <Container>

  12. <Component />

  13. </Container>

  14. )

  15. }

  16. }

  17.  
  18. export default MyApp

  19. 复制代码

对比这一段代码,这里从next/app中多引入了一个Container组件,并在中间重新写了一个MyApp类,继承自App,最后将其返回。在MyApp中,重写了render方法来渲染组件,其中从props中拿到的Component组件就是在访问每个pages下的js文件时候,这些文件返回的组件。想想也是,在写react的时候,其他组件要显示也是要包裹在最外层的App组件中的,这里是一样的道理。 值得注意的是,这里的MyApp组件返回Component时候最外层要使用Comtainer组件进行包裹。我们可以顺手打印出Component,看看到底是不是向我们所说的一样。

 

 

重写getInitialProps

不过现在并不算完成,我们连App原本的功能还没实现完整:在当前组件中,我们是拿不到其他页面getInitialProps()方法初始话的数据的,如果对getInitialProps()不了解,请翻阅很简单的next.js数据获取规范或者官方文档 这里可以给大家看一个例子

 

这里在getInitialProps()中定义的数据并没有显示出来

 

 
  1. class MyApp extends App {

  2. static getInitialProps = async ({Component}) => {

  3. let pageProps;

  4. if(Component.getInitialProps) {

  5. pageProps = await Component.getInitialProps()

  6. }

  7. return {

  8. pageProps

  9. }

  10. }

  11.  
  12. render() {

  13. const { Component, pageProps } = this.props;

  14. console.log(Component);

  15.  
  16. return (

  17. <Container>

  18. <Component {...pageProps} />

  19. </Container>

  20. )

  21. }

  22. }

  23. 复制代码

这里在MyApp中新增了一个getInitialProps方法,注意他是一个静态方法,由于其他页面可能设置了getInitialProps也可能没有设置,所以这里需要判断一下,并且这个方法为异步方法,执行时注意加上await并在外层方法添加async。这样就可以将其他页面中getInitialProps设置的属性引入过来,并且传递给Component就可以显示了,来看看效果吧

 

 这里就可以正常打印了

 

管理全局数据举例

 
  1. state = {

  2. counter: 20

  3. }

  4. 复制代码

例如在MyApp中定义counter,就可以传递给所有组件 布局示例 在components目录下创建Layout.jsx

 
  1. import Link from 'next/link';

  2. import { Button } from 'antd'

  3.  
  4. export default ({ children }) => {

  5. return (

  6. <>

  7. <div className="header">

  8. <Link href="/a?id=1"><Button>跳转A</Button></Link>

  9. <Link href="/test/b"><Button>跳转B</Button></Link>

  10. </div>

  11. <div className="body">

  12. {children}

  13. </div>

  14. </>

  15. )

  16. }

  17. 复制代码

然后在_app.js中引用

 
  1. return (

  2. <Container>

  3. <Layout>

  4. <Component {...pageProps} />

  5. </Layout>

  6. </Container>

  7. )

  8. 复制代码

这样每个页面都会显示Layout了

自定义Document

只有在服务器端渲染的时候才会被调用,主要用来修改服务端渲染的文档内容,通常实现服务端渲染会使用一些css-in-js库(styled-jsx是 Next.js自带默认使用的css-in-js库) 它在_document.js中定义

 
  1. import Document, {Html, Head, Main, NextScript} from 'next/document'

  2.  
  3. class MyDocument extends Document {

  4. render() {

  5. return (

  6. <Html>

  7. <Head>

  8. </Head>

  9. <body>

  10. <Main />

  11. <NextScript />

  12. </body>

  13. </Html>

  14. )

  15. }

  16. }

  17. export default MyDocument

  18. 复制代码

next/document中提供的并不仅是Document组件,还有一些跟HTML标签对应的组件,在重写的时候要记得都要写上。

在Head中试着添加一些内容

 
  1. <Head>

  2. <title>My Next.js</title>

  3. <style>{`* { color: red}`}</style>

  4. </Head>

  5. 复制代码

 

 

 

设置getInitialProps

再说明一下,document只有在服务端渲染时候才会执行。

在重写Docuemnt的时候,我们也可以重写getInitialProps方法,这个getInitialProps来自于Document组件。

 
  1. static getInitialProps = async (ctx) => {

  2. const props = await Document.getInitialProps(ctx)

  3.  
  4. return {

  5. ...props

  6. }

  7. }

  8. 复制代码

这里的getInitialProps也是个静态方法,并且也要加async,因为里面使用了await,并且注意有个参数ctx,我们可以不重写它,但是如果我们要重写就要按照这个格式来重写,然后在里面再添加自己想要的东西。

结束

本文内容是比较简单的,但是很重要,在使用next.js开发项目中是要经常使用的,所以还是掌握好它吧。在后面集成css in js样式文章中可能还会再比较详细地描述在_docuemnt.js中我们可以干点什么,希望对入门级小伙伴有所帮助。

转载于:https://juejin.im/post/5cc08f0de51d453f38191d64

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值