NextJSHeadComponent NextJSDocument
001 Жизненный цикл React
Реакт - это в первую очередь библиотека, так как в ней нет полноценного роутинга, архитектуры и остальных частей полноценного фреймворка. Реакт-компонент на странице представляет собой как целую страницу, так и отдельную кнопку.
На примере мы видим отдельный реакт-компонент. На входе он принимает от родителя пропсы. На выходе (return()
) он должен будет отдать JSX-элемент. В результате этого JSX-элемента, мы говорим, что мы хотим отобразить этим компонентом в целом.
Основная цель реакта - это фокус на том, как нужно отрендерить эти элементы и компоненты и когда нам нужно перерендерить их
В рамках рендера компонент проходит несколько циклов. Жизненный цикл реакта делится на две большие части:
- Первичный Рендер (генерация страницы либо на клиенте, либо на сервере). Тут мы работаем с ДОМ, выполняем некоторые побочные эффекты. Конкретно этот этап будет проходить на сервере, так как мы используем NextJS
- Коммит (отображение на странице, обновление ДОМ-дерева и срабатывание эффектов)
Делятся эти циклы на три состояния компонента:
- Mounting - монтирование страницы из компонентов. Тут происходит срабатывание функции и возвращение элемента реакта из
return
. Дальше выполнится обновление своего дерева элементов реакта и конечного дом-дерева. После построения дерева, происходят сайд-эффекты, которые мы можем вызвать хуками - Updating - обновление компонента на странице, когда с ним что-нибудь происходит (например, срабатывание эффектов)
- Unmounting (размонтирование) - удаление компонента со страницы и из дерева. При удалении элемента со страницы можно так же вызывать подключенную анимацию к компоненту
Обновляется компонент реакта в нескольких случаях:
- Когда у него поменялось состояние (
useState
,useReduce
) - Когда у него поменялся глобальный контекст (
useContext
) - И когда у него поменялся входящий
props
002 Компонент head
Компонент head
хранит в себе метаданные страницы и поднимает их на самый верх
index.tsx
export default function Home(): JSX.Element {
const author = " Lvov Valery";
return (
<div className={styles.container}>
<Head>
<title>Create Next App</title>
<meta name="description"content="Generated by create nextapp" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main></main>
);
}
И сразу нужно рассказать про особенности работы данного компонента:
title
берётся из самого верхнего по вложенности файла (тут -index.tsx
)- Чтобы разделять линки (например, если нам нужно другую фавиконку запилить на сайт), нужно проставить ключи на них
key={1}
_app.tsx
export default function App({ Component, pageProps }: AppProps): JSX.Element {
return (
<div>
<head>
<title>Second Page</title>
<link key={2} rel="icon" href="/favicon2.ico" />
</head>
<Component {...pageProps}/>
</div>
);
}
index.tsx
<link key={1} rel="icon" href="/favicon.ico" />
003 React Fragment
Компонент <Fragment>
позволяет отрендерить объект на странице без вложения внутрь div
-элемента. Его стоит использовать, чтобы не создавать лишней вложенности и реализовать передачу одного компонента реакта (див мы используем, чтобы не передавать массив объектов, который не может обработать библиотека)
До использования компонента:
После использования компонента лишнего дива нет
Это первый способ, которым мы можем вызвать компонент: <Fragment>
import '../styles/globals.css';
import type { AppProps } from 'next/app';
import { Fragment } from 'react';
export default function App({ Component, pageProps }: AppProps): JSX.Element {
return (
<Fragment>
<head>
<title>Second Page</title>
<link key={2} rel="icon" href="/favicon2.ico" />
</head>
<Component {...pageProps} />
</Fragment>
);
}
Так же мы можем вписать <React.Fragment>
import React from 'react';
export default function App({ Component, pageProps }: AppProps): JSX.Element {
return (
<React.Fragment>
<head>
<title>Second Page</title>
<link key={2} rel="icon" href="/favicon2.ico" />
</head>
<Component {...pageProps} />
</React.Fragment>
);
}
Ну и в конечном итоге мы можем просто написать <>контент</>
export default function App({ Component, pageProps }: AppProps): JSX.Element {
return (
<>
<head>
<title>Second Page</title>
<link key={2} rel="icon" href="/favicon2.ico" />
</head>
<Component {...pageProps} />
</>
);
}
004 Компонент Document
Если будут вопросы: https://nextjs.org/docs/advanced-features/custom-document
Данный компонент позволяет нам осуществить сразу несколько вещей:
- позволяет передать язык в наш документ
lang="ru"
(например, без этого параметра не будут работать скринридеры) - даёт возможность добавить класс в
body
, если потребуется - даёт нам возможность работать со структурой документа
Так же нужно отметить, что используется только на сервере
_document.tsx
import Document, {Html, Head, Main, NextScript, DocumentContext, DocumentInitialProps} from "next/document";
export default class MyDocument extends Document {
// эта функция берёт пропсы из основного документа и перебрасывает в наш
// таким образом, мы сохраняем пропсы в новом документе
static async getInitialProps(context: DocumentContext): Promise<DocumentInitialProps> {
const initialProps = await Document.getInitialProps(context);
return { ...initialProps };
}
// тут происходит рендер HTML-структуры нашего документа
render(): JSX.Element {
return (
<Html lang="ru">
<Head/>
<body className="someClass">
<Main/>
<NextScript/>
</body>
</Html>
);
}
}