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.