preface

This article will introduce you to customizing App components, Document components, and when you need to customize them in Next. This will probably be something we do in every project, So let’s master it together.

Tips: According to the convention, I am also an entry level player, the depth of the article can not reach the master level of the article, I only hope to help you entry level partners.

Custom App

First of all, let’s talk about why we need to customize our App. The App here is actually the root component when we write react. 1) By rewriting the _app.js file, we can reconstruct the App components and add some unchanged contents in the project, such as the layout of the page;

2) Keep the public state in the App. The public state here can also be some global CSS, such as ANTD. CSS added in the previous article about setting up the environment;

3) and passing custom data to the page,

4) Use componentDidCatch to customize handling errors;

5) Inject additional data into the page (such as GraphQL query)

In next. Js + KOa2 + ANTD easy setup, we wrote _app.js to introduce ANTD CSS. Here we do nothing but introduce ANTD. CSS, after introducing antD. CSS, it will apply globally.

import App from 'next/app'
import 'antd/dist/antd.css'
export default App
Copy the code

Now let’s make some changes to it

import App, { Container } from 'next/app'
import 'antd/dist/antd.css'

// Add this paragraph
class MyApp extends App {
    render() {
        const { Component } = this.props; 
        console.log(Component);

        return (
            <Container>
                <Component />
            </Container>)}}export default MyApp
Copy the code

In contrast to this code, we import an extra Container component from next/app and rewrite a MyApp class in the middle that inherits from App and returns it. In MyApp, the Render method is overridden to render components, where the Component from props is the Component that is returned when accessing the JS files under each pages. Think about it. When you write react, the other components will be displayed inside the outermost App component. Note that the MyApp Component returns the Component wrapped in the Comtainer Component. We can just print out the Component and see if it looks exactly like what we said.

rewritegetInitialProps

However, it is not complete now, we have not even completed the original functions of the App: There is no way to get the initial method getInitialProps() on any other page in this component. If you don’t know getInitialProps(), check out the simple Next-.js data retrieval specification or the official documentation for an example

getInitialProps()

class MyApp extends App {
    static getInitialProps = async ({Component}) => {
        let pageProps;
        if(Component.getInitialProps) {
            pageProps = await Component.getInitialProps()
        }
        return {
            pageProps
        }
    }

    render() {
        const { Component, pageProps } = this.props;
        console.log(Component);

        return (
            <Container>
                <Component {. pageProps} / >
            </Container>)}}Copy the code

This is a static method, because getInitialProps may or may not be set on other pages, and this method is asynchronous. Execute with await and add async to the outer method. This lets you import the properties set by getInitialProps from other pages and pass them to Component to display them

Example for managing global data

state = {
    counter: 20
}
Copy the code

For example, by defining counter in MyApp, you can pass all component Layout examples to create layout.jsx in the Components directory

import Link from 'next/link';
import { Button } from 'antd'

export default ({ children }) => {
    return (
        <>
            <div className="header">
                <Link href="/a? id=1"><Button>Jump A</Button></Link>
                <Link href="/test/b"><Button>Jump B</Button></Link>
            </div>
            <div className="body">
                {children}
            </div>
        </>)}Copy the code

It is then referenced in _app.js

return (
    <Container>
        <Layout>
            <Component {. pageProps} / >
        </Layout>
    </Container>
)
Copy the code

Each page will now display the Layout

The custom Document

This function is called only for server-side rendering, and is mainly used to modify the content of the document rendered by the server. Often, the styled JSX server rendering will use some CSS-in-JS library (styled JSX is the default csS-in-JS library used by next.js), which is defined in _document.js

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

class MyDocument extends Document {
    render() {
        return (
            <Html>
                <Head>
                </Head>
                <body>
                    <Main />
                    <NextScript />
                </body>
            </Html>)}}export default MyDocument
Copy the code

Not only is the Document component provided in next/ Document, but there are other components that correspond to HTML tags that should be included when rewriting.

Try adding something in Head

<Head>
    <title>My Next.js</title>
    <style>{`* { color: red}`}</style>
</Head>
Copy the code

Set the getInitialProps

Again, document is executed only when rendered on the server.

When we rewrite Docuemnt, we can also override the getInitialProps method, which comes from the Document component.

static getInitialProps = async (ctx) => {
    const props = await Document.getInitialProps(ctx)

    return {
        ...props
    }
}
Copy the code

GetInitialProps is a static method, and async too, because we have await in it, and notice that there is a parameter CTX that we don’t have to rewrite, but if we do we have to rewrite it in this format, and then add whatever we want to it.

The end of the

This article is simple, but important, and will be used a lot in your next. Js development projects, so stay on top of it. What we can do in _docuemnt.js will probably be described in more detail in a later article integrating CSS in JS styles, hopefully to help beginners.