React Junior
207 subscribers
37 photos
462 links
Изучение React с нуля
加入频道
Next.js. getInitialProps - параметры

Тот же подход можно использовать для предварительной загрузки поста на сервере - страница post/[id]. Но тут нам нужно знать значение динамического параметра.

Получить его можно из того же объекта контекста, который передается в метод getInitialProps.

export default SinglePost({ post }) => {
// ...
};

SinglePost.getInitialProps = async ({ query }) => {
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts/${query.id}`
);
const post = await response.json();
return {
post,
};
};


#nextjs #серверныйрендеринг
👍4
Next.js + TypeScript

Для описания страниц в Next-приложении нам потребуется тип NextPage (импортируется из пакета next). Это дженерик, который принимает тип пропсов компонента.

#nextjs #серверныйрендеринг #typescript
👍2🔥1
Next.js. getServerSideProps

Вероятно, вместо getInitialProps лучше использовать getServerSideProps.

Идея такая же, но getServerSideProps работает ТОЛЬКО на сервере (не запускается при переходе между страницами на клиенте в режиме SPA. То есть данные запрашиваются один раз и переиспользуются при загрузке страницы любым способом.

Разница:

- getInitialProps это статический метод компонента, а getServerSideProps просто функция, которую нужно импортировать из файла страницы.
- getServerSideProps должна вернуть объект с полем props.
- так как getServerSideProps работает только на сервере, нам не требуется проверять наличие req.

#nextjs #серверныйрендеринг
👍4🔥1
Forwarded from Cat in Web
Все виды Server-side рендеринга в NextJS: SSR, CSR, SSG, ISR

Видео (рус.): https://www.youtube.com/watch?v=xg-lajRmCco

Видео на 15 минут с обзором различных способов рендеринга в современном фронтенде. Примеры в основном на Next.js (React).

CSR - Client Side Rendering

Самая привычная нам форма работы, при которой все запросы исходят с клиента и DOM полностью формируется на клиенте.
Из минусов:
- долгая первая загрузка бандла (потом его можно закешировать), при которой пользователь видит только пустую страницу
- плохая SEO, так как поисковик тоже видит пустую страницу

SSR - Server Side Rendering

В этом подходе сервер самостоятельно рендерит страницу (при необходимости получает для нее данные) и отдает на клиент уже готовый HTML, который затем проходит гидратацию и становится нормальным SPA. Это SEO friendly, тратит меньше ресурсов устройства, но требуется время для подготовки страницы на сервере.

SSG - Static Site Generation

Другой способ - отрендерить все страницы сразу же, во время сборки проекта, не дожидаясь запросов пользователя. Готовые HTML складываются на сервере и при запросе сразу отдаются без затрат времени на подготовку. Не подходит для контента который должен быть актуальным. Также сомнительный способ, если на вашем сайте тысячи страниц (например, большой блог).

ISR - Incremental Static Regeneration

Та же SSG, но с возможностью обновить сгенерированные страницы по таймеру.

#serversiderendering #nextjs #ssr #ssg #isr
👍4
Next.js. Ошибка гидратации

Иногда выскакивает ошибка типа:

next-dev.js?3515:20 Warning: Prop `className` did not match. Server: "sc-ipEyDJ SbBBO" Client: "sc-gswNZR cjWWhU"


И в конце сообщения ссылка https://nextjs.org/docs/messages/react-hydration-error.

Это ошибка гидратации, когда на сервере рендерится одно, а при первом рендере в браузере - другое. Она может возникать, если мы используем в коде условия, которые по разному вычисляются на сервере и на клиенте. Или при невалидной HTML-разметке.

В моем случае ошибка связана с библиотекой Styled Components: рендерятся разные классы для элемента.

Чтобы такого не было, нужно правильно настроить проект. Обязательно нужно добавить файл pages/_document и плагин babel-plugin-styled-components (файл .babelrc описан здесь https://dev.to/aprietof/nextjs--styled-components-the-really-simple-guide----101c).

Для Next.js 12.1+ достаточно добавить опцию в конфиг next.config.js. Описано здесь: https://nextjs.org/docs/advanced-features/compiler#styled-components

#nextjs #серверныйрендеринг #ошибки #стили #важно
👍1🔥1
Forwarded from Cat in Web
Roadmap для React-разработчика

https://roadmap.sh/react

От базовых концепций - компонентов и хуков - до тестирования и фреймворков. Полезная штука для представления современной React-экосистемы.

#react #roadmap
👍2
С Наступающим! 🎄
Интересных проектов, профессиональных достижений и прекрасного настроения в Новом году! Ура! 🎇
👍5🎉4🍾1🎄1
Forwarded from Cat in Web
12 хуков React, которые должен знать каждый разработчик

Статья (рус.): https://nuancesprog.ru/p/16589/

В статье есть реально классные библиотеки, которые стоит взять на заметку.

1. react-swipeable - для обработки свайпов
2. use-resize-observer - позволяет изменять размеры элемента и измерять их
3. formik - для всей рутины с формами (валидация, посещенные поля и т.д.)
4. use-debounce - позволяет отслеживать какие-то изменения с задержкой для увеличения производительности
5. use-isomorphic-layout-effect - нужен для SSR, так как на сервере нельзя использовать хук useLayoutEffect
6. swr - библиотека для получения данных (stale-while-revalidate)
7. react-hotkeys-hook - для работы с горячими клавишами
8. @use-gesture/react - обработка жестов и различных событий
9. react-script-hook - для динамической загрузки внешних скриптов
10. react-scroll-parallax - для реализации параллакса при скроллинге
11. react-storage-hooks - для синхронизации состояния приложения с хранилищем (`localStorage`/`sessionStorage`)
12. @chakra-ui/color-mode - поддержка светлого и темного режимов

#react #hooks #библиотеки
👍3
Next.js. SSG

Сегодня забежим вперед и глянем одним глазом на SSG в Next.js - Static Site Generation.
Сразу предупреждаю: делается это только из неутолимого интереса и больше наощупь, чем по проверенным рецептам.

Итак, предполагается, что при сборке все странички сразу должны отрендериться с начальными данными и появиться в проекте в виде готовых HTML-документов.

Вместо getServerSideProps нужно использовать функцию getStaticProps (сигнатура у нее практически такая же).
Нужно внести изменения на страницах posts и post/[id].

С posts никаких проблем не возникло, а вот с динамическим роутом все сложнее. Там мы вытаскиваем id поста из параметра context.query, но при статической генерации никакого query у нас не будет. И как вообще понять, какие у нас есть посты и какие страницы для них генерировать?

Для этого есть еще одна функция getStaticPaths, которая как раз и должна вернуть нам все необходимые урлы. Их нужно вернуть в поле paths (массив):

export const getStaticPaths: GetStaticPaths = async function() {
const paths = [
{ id: '1' },
{ id: '2' },
{ id: '3' }
];

return {
paths,
fallback: false,
};
};


Функция асинхронная, так что внутри нее можно выполнить, например, запрос к базе данных и получить айдишники всех существующих постов.

Теперь в функцию getStaticProps нам будут приходить параметры для каждого поста. Их можно получить из поля params.

export const getStaticProps: GetStaticProps = async function(context) {
const { id } = context.params;
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts/${id}`
);
const post = await response.json();
return {
props: {
post
}
}
}


Теперь запускаем команду npm run build и смотрим в папку .next/server/pages. Тут можно найти все наши странички уже в виде HTML. Кроме того, для каждой страницы генерируется еще JSON-файл с данными.

#nextjs #серверныйрендеринг #примерыкода
👍3🔥1
Next.js. API

Next позволяет легко создавать эндпоинты API.

Создаем в папке pages новую папку api, а в ней - файлы для эндпоинтов.
Из каждого файла нужно по дефолту экспортировать функцию, которая будет обрабатывать запрос.

export default function echo(req, res) {
res.status(200).json({
message: req.query.message,
});
}


Обратиться к нему можно по урлу /api/echo?message=SomeText.

В папке api также можно создавать роуты с динамической частью: pages/api/[id].ts. Динамический параметр можно получить из req.query.id.

#nextjs #серверныйрендеринг
👍3🔥2
Переходим к нашему любимому чтению документации: https://nextjs.org/docs/getting-started

В курсе есть еще несколько интересных моментов, например, работа с TypeScript, файл конфигурации и библиотека для отображения состояния загрузки при переходе между страницами, но первые два я планирую разобрать по документации, а третий пока выглядит больше как магия, нужно копнуть Next чуть глубже, чтобы понять, что там происходит.

#документация #nextjs #серверныйрендеринг
👍4
Next.js. Начало работы

Статьи в документации (англ.):
https://nextjs.org/docs/getting-started
https://nextjs.org/docs/basic-features/pages

Проще всего начать работу с помощью утилиты create-next-app (есть флаг --typescript`) , но можно и вручную все сделать. Для этого нужно к обычному React-приложению (`react, react-dom`) добавить еще пакет `next и пару npm-скриптов для запуска. Все самое приятное уже есть из коробки - сборка, запуск сервера, быстрое обновление.

У нас есть две важные папки - pages и public. Про страницы мы уже в целом знаем.

Нам снова рассказывают про SSG (Static Generation, генерация во время сборки) и SSR (Server Side Rendering), говорят, что эти подходы можно совмещать, но сильно рекомендуют SSG. Говорят, что если не получается чистый SSG, то можно сделать SSG для костяка страницы, а данные запрашивать уже на клиенте.

#документация #nextjs #серверныйрендеринг
🔥3👍1
Next.js. Data Fetching

Статьи в документации (англ.):
- https://nextjs.org/docs/basic-features/data-fetching/overview
- https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props
- https://nextjs.org/docs/basic-features/data-fetching/get-static-paths
- https://nextjs.org/docs/basic-features/data-fetching/get-static-props

Чтобы заполнить наши шаблоны данными, нам необходимо эти данные получить. Делать это можно в разное время, как мы уже знаем:

- в рантайме при запросе к странице - getServerSideProps
- при сборке - getStaticProps + getStaticPaths
- на клиенте - useEffect

getServerSideProps

При каждом запросе к странице Next.js (на сервере) будет выполнять функцию getServerSideProps и рендерить компонент страницы с полученными данными. На клиенте эта функция никогда не выполняется и вырезается из клиентского бандла.
Если мы переходим на страницу с помощью next/link или next/router, функция тоже выполняется (API-запрос).

Использовать эту функцию нужно в том случае, если данные необходимо получать именно во время запроса (авторизация/гео-локация/актуальные данные).

Документация советует не использовать API-роуты (папка pages/api) внутри getServerSideProps, так как это снижает производительность. Лучше напрямую выполнять запросы из функции.

Функция имеет доступ к объекту запроса (ctx.res). Это позволяет управлять кэшем:

export async function getServerSideProps({ req, res }) {
res.setHeader(
'Cache-Control',
'public, s-maxage=10, stale-while-revalidate=59'
)

return {
props: {},
}
}

При возникновении ошибки в getServerSideProps рендерится страница 500 ошибки.

getStaticPaths

Функция необходима для динамических роутов, чтобы указать, какие значения могут принимать динамические параметры. Она возвращает объект с двумя полями paths и fallback (false/true/'blocking', разберемся с этим параметром чуть позже).

Здесь можно обратиться к базе данных/файловой системе и получить все возможные значения параметров.

Функция выполняется только при сборке и не входит в клиентскую сборку, так что здесь смело можно писать серверный код (например, обращение к БД). В режиме разработки функция выполняется при каждом запросе.

Необходимо использовать вместе с getStaticProps, так как нужно передать полученные динамические параметры на страницу.

getStaticProps

Идея та же, что и у getServerSideProps, но выполняется не в рантайме, а во время сборки. Является предпочтительным методом запроса данных.

Выполняется только на сервере, не входит в клиентскую сборку.

Документация советует не использовать API-роуты (папка pages/api) внутри getStaticProps, так как это снижает производительность. Лучше напрямую выполнять запросы из функции.

Не имеет доступа к объекту запроса.

При выполнении функции getStaticProps Next.js генерирует HTML-файл и вдобавок к нему JSON-файл, который используется, если на страницу переходят на клиенте с помощью next/link или next/router. То есть запросы заново не выполняются, берутся те данные, которые были получены при сборке.

В режиме разработки функция выполняется при каждом запросе.

#nextjs #серверныйрендеринг #документация
👍2
Next.js. Инкрементальная статическая регенерация

Если мы используем подход SSG, то для внесения любых изменений нужно пересобрать приложение (например, если появились новые посты).

Но Next позволяет избежать пересборки - этот подход называется ISR - Incremental Static Regeneration. Для его использования нужно только добавить поле revalidate в результат функции getStaticProps:

export async function getStaticProps() {
...
return {
props: {},
revalidate: 10
}
}


Значение - это количество секунд, по истечении которых нужно обновить пропсы. То есть мы делаем первый запрос, функция выполняется и результат кешируется на 10 секунд. После этого времени для нового запроса функция будет выполнена заново.

#nextjs #серверныйрендеринг #документация
👍2🔥1
Next.js. useSWR

Для запроса данных на стороне клиента нам настойчиво рекомендуют библиотеку SWR, которая предоставляет много плюшек вроде кеширования, ревалидации, перезапроса данных и т.д.

#nextjs #серверныйрендеринг #документация
👍3🔥1
Next.js. getStaticPaths - fallback

Параметр fallback определяет поведение Next.js при обращении к странице с несуществующим динамическим параметром.

fallback: false

Если fallback: false, то для неперечисленных параметров будет возвращаться страница 404. Это удобно, если у вас не очень много роутов и они не часто добавляются.

fallback: true

Если fallback: true, то при обращении к странице с несуществующим параметром будет возвращена "резервная" версия страницы.

Резервная - значит, с пустыми пропсами. При этом у объекта роутера поле isFallback будет равно true:

import { userRouter } from 'next/router';

function Post({ post }) {
const router = useRouter();

if (router.isFallback) {
// рендеринг экрана загрузки
}

// рендеринг поста
}


Резервная страница будет отображаться до тех пор, пока Next в фоновом режиме не сгенерирует HTML и JSON для новой страницы (getStaticProps). Затем браузер получит JSON и отрендерит новую страницу, а новый путь добавится в список "уже отрендеренных". По сути у нас тут SSR.

Этот подход полезен, если у вас очень много страниц, которые зависят от данных (например, товары в интернет-магазине). Если рендерить страницы для всех товаров при сборке, это займет слишком много времение, поэтому изначально рендерим лишь некоторые страницы (getStaticPaths) и включаем fallback: true.

При запросе неуказанных товаров будет выполняться getStaticProps в фоновом режиме, а пользователь будет видеть резервную версию страницы, пока она не загрузится.

fallback: 'blocking'

Если fallback: 'blocking', то будет то же самое, что и для fallback: true, но резервная страница во время загрузки отображаться не будет.

#nextjs #серверныйрендеринг #документация
👍4
Next.js. Layouts

Статья в документации (англ.): https://nextjs.org/docs/basic-features/layouts

Лейауты - отдельные компоненты, которые предоставляют как бы HTML-обертку для наших страниц. Например, в лейаут можно добавить шапку и футер, общие для всех страниц, и таким образом подключать их.

Если у нас для всех страниц один лейаут, то проще всего подключить его в файле pages/_app.js (это компонент, инициализирующий активную страницу, подробнее здесь). Просто импортируем нужный лейаут и оборачиваем им контент страницы.

Если же у разных страниц разные лейауты, нужно идти другим путем.

Проще всего указать нужный лейаут прямо в теле компонента страницы, но тут есть один нюанс. Если в лейауте есть какое-то состояние (например, поле ввода), то при смене страниц оно будет сбрасываться, даже если лейаут один и тот же.

Демо: https://codesandbox.io/p/sandbox/jolly-agnesi-w90pmj?file=%2Fpages%2Fcomponents%2FLayoutWithState.tsx&selection=%5B%7B%22endColumn%22%3A24%2C%22endLineNumber%22%3A15%2C%22startColumn%22%3A24%2C%22startLineNumber%22%3A15%7D%5D

У нас есть две страницы, которые подключают в своем теле компонент LayoutWithState. Этот компонент имеет внутреннее состояние (useState). При переключении между страницами это состояние сбрасывается.

Документация предлагает нам использовать другой паттерн.

Мы можем добавить нашим страницам статический метод getLayout, который будет возвращать нужную обертку. Если вы используете TypeScript, понадобится создать новый тип NextPageWithLayout, расширяющий NextPage.

Внутри компонента-инициализатора App проверяем, есть ли у текущией страницы этот метод. Если есть, то вызываем его, чтобы получить нужную разметку.

Для обеих страниц переносим рендер обертки в метод getLayout. Теперь при переключении страницы состояние в лейауте сохраняется, так как React не заменяет компонент обертки на новый экземпляр.

Демо: https://codesandbox.io/p/sandbox/next-js-layouts-react-junior-forked-vl930n?file=%2Fpages%2F_app.tsx&selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A21%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A21%7D%5D

#nextjs #серверныйрендеринг #примерыкода #документация
👍2🔥2
Next.js. Изображения

Статьи в документации (англ.):
- https://nextjs.org/docs/basic-features/image-optimization
- https://nextjs.org/docs/api-reference/next/image

Next.js предоставляет собственный компонент Image, который является оберткой над стандартным img. Этот компонент умеет много полезного, например, самостоятельно может определять размеры изображений, чтобы предотвратить кумулятивный сдвиг страницы (CLS), реализует ленивую загрузку, умеет отображать плейсхолдер - и это наверняка не все его достоинства.

Основные атрибуты у него стандартные: src, alt, width и height, с тонкостями разберемся далее.

#nextjs #серверныйрендеринг #документация
👍4🔥1
Next.js. Image. Источник изображения

Image может работать и с локальными, и с удаленными файлами, причем с локальными - больше плюшек.

Локальные изображения

Изображения проекта должны храниться в папке public. Импортируем их в нужный компонент и передаем в проп src компонента Image.

Для таких изображений даже необязательно указывать width и height, если они не отличаются от оригинальных. Во время сборки Next проанализирует файл изображения, определит его размеры и подставит самостоятельно.

Динамический импорт не поддерживается.

Удаленные изображения

В src можно указать и обычный урл (относительный или абсолютный). Если используются абсолютные пути, то домены обязательно нужно добавить в файл next.config.js в секцию images.remotePatterns.

module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com',
},
],
},
}


#nextjs #серверныйрендеринг #документация
👍5
Next.js. Image. srcset

Компонент Image рендерит стандартный тег img и проставляет для него массу полезных атрибутов, например, srcset. Что именно в нем будет, зависит от пропа sizes (https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/sizes). Если этот проп не передан, будет всего пара размеров, но может быть и очень большой список.

srcset генерируется и для локальных, и для удаленных изображений.

Видео (англ.): https://www.youtube.com/watch?v=R4sdWUI3-mY&ab_channel=BrunoAntunes

В начале видео очень подробно и понятно рассказывается об атрибутах srcset и sizes. Вторая часть (про Next.js) немного устарела, с момента записи произошли некоторые изменения.

#nextjs #серверныйрендеринг #документация
👍3🔥1