React Junior
207 subscribers
37 photos
462 links
Изучение React с нуля
加入频道
JSX Style

И наконец, последний в списке способ стилизации React-компонентов - JSX Style (есть еще утилитарные фреймворки, но это не специфический для React подход).

Репозиторий jsxstyle: https://github.com/jsxstyle/jsxstyle

jsxstyle предлагает указывать стили в inline-режиме, то есть не выносить их в отдельный объект, а писать прямо в пропсах компонентов. Библиотека предоставляет несколько готовых компонентов с уже предустановленными стилями отображения (Block, Inline, Row и т. п.). При этом скомпилированные стили не остаются инлайновыми, а превращаются в нормальные CSS-таблицы, а компонент трансформируется в обычный HTML-тег с каким-то уникальным классом.

Пример: https://codesandbox.io/s/jsxstyle-react-junior-wn88n?file=/src/App.js

jsxstyle утверждает, что самое сложное в CSS - придумывать названия для классов, поэтому они полностью избавились от них, предоставив готовые блоки и максимально утилитарный стиль использования.

В целом, это немного другой способ "думать о стилях", чем те, которые мы разбирали ранее. Документация утверждает, что он проще и удобнее для работы и для оптимизации. 🤔

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

Атрибуты, которые не относятся к стилям и должны быть установлены прямо на HTML-элемент (вроде placeholder, type) можно передать в пропе props. Хотя в документации сказано, что такие свойства как placeholder, type, id можно указывать и на верхнем уровне компонента, но у меня это почему-то не сработало.

Поддерживаются псевдоэлементы и псевдоклассы. Чтобы задать, например, цвет плейсхолдера, нужно использовать свойство placeholderColor, а для изменения цвета при фокусе - focusColor.

Медиа-запросы тоже есть. Чтобы их использовать нужно указать список запросов в пропе mediaQueries, как объект, где у каждого запроса есть имя. Затем эти имена нужно использовать как префиксы для стилевых пропсов.

В качестве альтернативы такому громоздкому синтаксису можно использовать хук useMatchMedia.

В целом, мне не очень нравится образ мышления "jsxstyle", возможно, мой мозг для него еще просто не готов 🤯. Код получается, возможно, и более понятным (или нет), но уж точно намного более раздутым. Но что еще хуже, нет развернутой документации, только readme в репозитории. Так что дальше углубляться в jsxstyle, пожалуй, не буду.

#стили #jsxstyle #примерыкода
👍2👏1
CSS-переменные для React-разработчиков

Статья (англ.): https://www.joshwcomeau.com/css/css-variables-for-react-devs/

CSS-in-JS решения позволяют писать очень гибкие стили, но не следует забывать про нативные возможности CSS. Автор статьи считает, что CSS-переменные aka кастомные свойства - это очень мощный инструмент, который иногда может переплюнуть все эти ваши JS-интерполяции.

CSS-переменные дают возможность изменять значения, а не свойства. Они декларативны, и код с ними становится короче и чище. CSS-переменные наследуются вложенными элементами, а при необходимости с ними можно легко взаимодействовать из JS-кода. Ко всему прочему, с помощью переменных можно анимировать то, что нельзя анимировать другими способами, например, градиенты (с некоторыми оговорками).

В статье рассмотрен конкретный кейс обеспечения доступности кнопки на тач-устройствах - в двух вариантах: CSS-in-JS (Styled Components) и CSS-переменные.

В целом полностью поддерживаю мнение автора, CSS-переменные - очень мощная штука, к тому же нативная.

#стили #ссылки
👍1
По итогам опроса CSS Модули и препроцессоры вырвались вперед :) React JSS догоняет, остальные отстают.

Лично я также склоняюсь к комбинации модулей (для изоляции стилей) и препроцессоров (для удобства написания). Видимо, во мне живет консерватор, который любит писать стили в отдельном файлике в привычном виде, чтобы не засорять ими JS-код.

Из других решений мне более симпатичен React JSS. У Styled Components не нравится синтаксис, Radium кажется недоделанным, JSX Style избыточным, а React Shadow слишком радикальным.

#стили
👍4👏1
React Router

Так как в SPA переключение между страницами осуществляется без перезагрузки, необходимо какое-то решение для маршрутизации. Для этого в основном используется React Router.

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

Мы начнем знакомство с роутером с гайда Robin Wieruch (англ.): https://www.robinwieruch.de/react-router/

NPM-пакет, который нам нужен, называется react-router-dom, очевидно, эта реализация предназначена именно для работы в браузере. Разумеется, вся функциональность оформлена в виде React-компонентов и хуков.

🔷 Важные компоненты

🔸 BrowserRouter

Корневой компонент, внутри которого и происходит вся магия маршрутизации. Оборачивает все приложение (или ту его часть, где требуется управление роутингом).

🔸 Link

Компонент-ссылка, используется вместо обычных a. Вместо атрибута href есть проп to.
При нажатии на Link текущий урл изменяется, но перезагрузки не происходит.

🔸 NavLink

Аналог Link, который знает о текущем активном роуте и может иметь "активное" состояние (класс .active, а также проп `isActive`). Удобно использовать для главного меню сайта, чтобы выделять раздел, который пользователь просматривает в данный момент.

🔸 Route

Компонент отдельного роута. Имеет проп path, содержимое которого сопоставляется с текущим урлом, и проп element, в который нужно передать разметку, которая должна быть отрендерена.
Если указанный роут совпадает с текущим, он рендерится.
Таким образом, атрибут to компонента Link соответствует атрибуту path компонента Route.

🔸 Routes

Обязательный контейнер для элементов Route, которых может быть сколько угодно.
Внутри Routes всегда рендерится только один роут, первый подходящий.

🔸 Outlet

Роуты должны быть единственными потомками компонента Routes (еще могут быть React.Fragment), но их можно вкладывать друг в друга. При этом чтобы внутри родительского компонента отображались вложенные роуты (если они активны), используется компонент Outlet (аналог `props.children`).

🔷 Роуты

🔸 Без роута

У элемента Route может не быть пропа path, например, если это компонент-обертка (`Layout`), которые оборачивает все роуты и выводится всегда.

🔸 Index

Для обозначения корневого роута используется проп index. В этом случае path указывать не нужно.

🔸 Not Found

Если не один роут из списка не подошел, можно вывести запасной вариант - обычно это страница 404. Для этого в пропе path нужно указать *.

🔸 Динамические роуты

Если требуется передать в роуте какой-то динамический параметр, например, id товара на страницу каталога, в компоненте Route его нужно указать с помощью : (`:productId`).

Получить значение параметров можно с помощью хука useParams.

🔸 Вложенные роуты

Если роуты вложены друг в друга, то значения их путей складываются.

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

🔷 Программная навигация

Для программной навигации по роутам используется хук useNavigate, который возвращает функцию navigate. Чтобы перейти на какой-то роут, нужно просто передать его параметром в эту функцию.

🔷 Гет-параметры

В урле кроме основного пути могут быть еще дополнительные параметры запроса (search params). При необходимости их можно получить с помощью хука useSearchParams. Он возвращает стандартный кортеж (массив значений) - первым идет сам объект с параметрами, а вторым - метод для его обновления.

Удобно использовать, например, для сохранения значений различных фильтров.

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

#ссылки #роутинг
👍1👏1
Проект

Небольшой проект для закрепления материала: https://codesandbox.io/s/project-1-react-junior-oso5s?file=/src/App.js

Описание

Это демка интернет-магазина резиновых уточек.

Есть главная страница, на которой выводится ассортимент товаров. Каждый товар можно добавить в корзину или удалить, если он уже добавлен.

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

Кроме того есть отдельная страничка с информацией о магазине.

Данные

Для симуляции получения данных с сервера используются методы getProducts() и getProduct(id). Список продуктов запрашивается в компоненте App (внутри хука useEffect). Состав корзины также хранится здесь.

Стили

Для стилизации используется React JSS.

Приложение обернуто в ThemeProvider, в отдельных компонентах для получения темы используется хук useTheme.

Маршрутизация

Для маршрутизации используется React Router. Все приложение обернуто в компонент BrowserRouter.

Главный компонент приложения - App. Здесь определяются все роуты:

- индексный - компонент Catalog
- роут about - компонент About
- роут cart - компонент Cart
- и вложенный в cart роут с динамическим параметром :productId - компонент ProductView

Также есть дефолтный роут *, связанный с компонентом NotFound.

Все роуты обернуты в роут без пути, связанный с компонентом Layout, который обеспечивает общую разметку.

Чтобы в компоненте Корзины мог отображаться вложенный компонент ProductView, используется компонент Outlet.

В шапке есть маленькое навигационное меню, созданное с помощью компонентов NavLink. Они хранят состояние, активный роут выделяется цветом. Прочие навигационные ссылки сделаны с помощью Link.

Программная навигация

При удалении товара из корзины роут программно изменяется.

Гет-параметры

На странице каталога есть поле поиска по товарам, оно синхронизируется с гет-параметром filter с помощью хука useSearchParams.

Прочее

Для пробы добавлен кастомный хук useFilteredList.

#роутинг #хуки #стили #примерыкода
👏1
Несколько статей

Несколько ссылок, надерганных из предыдущей статьи про роутер (все англ.):

🔸 Структура папок в React проекте за 5 шагов

https://www.robinwieruch.de/react-folder-structure/

Описано 5 способов группировки файлов по папкам в зависимости от размера проекта. От единственного файла, до разделения компонентов по доменам (отдельно компоненты, связанные с юзером, отдельно каталог и т.п.)

В целом ничего нового, но полезно, чтобы составить более оформленное представление.


🔸 CSS в React

https://www.robinwieruch.de/react-css-styling/

Еще один обзор разных способов стилизации приложений, большинство из которых мы уже довольно подробно разобрали. Способы разделены на три стратегии CSS-in-CSS, CSS-in-JS и Utility-First-CSS.

Заинтересовала именно последняя секция, про утилитарный CSS (Tailwind). Там куча разных классов, предполагается, что с их помощью можно настроить все, что нужно, без единой строчки CSS. Например, есть класс py-2, который устанавливает вертикальные паддинги, или border-solid для стиля рамки. Выглядит ужасно, но может быть очень удобно для быстрого наброска/прототипирования/какого-нибудь небольшого демо-проекта.


🔸 Вложенные роуты в React Router 6

https://www.robinwieruch.de/react-router-nested-routes/

Более подробный разбор вложенных роутов. Это когда у вас есть, например, Личный Кабинет пользователя но роуте /user, а в нем две вкладки: Личные данные (`/user/personal`) и История заказов (`/user/orders`). Общая часть страницы отображается всегда, а какая именно вкладка будет видна - зависит от урла и является частью роутинга.

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

Вложенные роуты могут быть динамическими (например, id пользователя). В этом случае мы можем получить конкретное значение с помощью хука useParams.


🔸 Параметры поиска в React Router 6

https://www.robinwieruch.de/react-router-search-params/

Более подробный разбор работы с гет-параметрами. В React Router для этого есть хук useSearchParams, он возвращает актуальный объект URLSearchParams и позволяет изменять его. Чтобы было удобнее, можно написать собственный хук, который превращает URLSearchParams в обычный объект. Или можно воспользоваться уже готовым решением use-query-params.

#проект #роутинг #стили #ссылки
👍2
Документация React Router

Начинаем читать документацию React Router, чтобы узнать его получше.

https://reactrouter.com/docs/en/v6

Сначала общий обзор:

1. React Router DOM

В npm можно найти три пакета: react-router, react-router-dom и react-router-native. В первом находится ядро роутера, а два других - это конкретные реализации для браузера и для нативных приложений. React-router-dom и react-router-native уже импортируют все из react-router, поэтому нам не нужно использовать основной пакет.

2. Роутеры

Чтобы маршрутизация работала, нужно обернуть приложение в один из предоставленных корневых компонентов - роутеров. Для веба есть BrowserRouter (уже использовали) и HashRouter. Кроме того есть роутеры для серверного рендеринга, нативных приложений и тестирования, они нас пока не очень интересуют. Все роутеры обеспечивают контекст для работы остальных компонентов.

3. Роуты

Есть два способа объявить роуты:
- прямо в JSX-разметке с помощью компонентов Routes и Route
- с помощью хука useRoutes из JS-кода

4. Навигация

Можно управлять роутингом, то есть изменять текущий урл и, соответственно, отображаемые компоненты React. Для этого есть компоненты Link и NavLink (аналоги обычных ссылок), а также компонент Navigate и хук useNavigate для программного управления.

5. Гет-параметры

Для работы с гет-параметрами урла предназначен хук useSearchParams.

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

#документация #роутинг
Роутеры

BrowserRouter

Стандартный роутер для маршрутизации в браузере. Использует History API для управлния урлом и изменения текущего роута. По умолчанию работает с текущим окном, но это можно изменить с помощью пропа window.

Hash Router

Компонент HashRouter - это альтернатива BrowserRouter, которая контролирует не весь урл веб-страницы, а только его хеш. Документация не рекомендует использовать этот тип маршрутизации без крайней необходимости, если вы почему-то не можете отправлять урл на сервер.

Memory Router

MemoryRouter хранит всю информацию в обычном массиве и не связан с внешними api. Его удобно использовать для тестирования. У него есть пропсы initialEntries (принимает массив строк) и initialIndex (принимает число), с помощью которых можно установить "исходную" историю маршрутизации.

#документация #роутинг
👍1
Современный технический стек React: самые популярные инструменты

Статья (англ.): https://profy.dev/article/react-tech-stack

Обзор самых популярных инструментов в экосистеме React для решения самых разных задач: от обработки форм до тестирования. Будет полезен начинающим разработчикам, у которых (как у меня) глаза разбегаются, и непонятно, за что хвататься.

Оценка популярности базируется в основном на количестве загрузок в npm, но учитываются и другие источники информации (например, опрос State of JS).

🔶 1. Библиотеки

Next.js - самый популярный React-фреймворк.
Redux - самый популярный стейт-менеджер.
react-query - самая популярная библиотека для запроса данных (или Apollo для проектов, использующих GraphQL).
React Hook Form - самая популярная библиотека для работы с формами.
styled-components и MUI - самые популярные библиотеки для работы со стилями (MUI - библиотека компонентов)

🔶 2. Инструменты разработки

Prettier - для форматирования кода.
ESLint - для статического анализа кода и отлова плохих паттернов.
TypeScript - для проверки типов.

🔶 3. Тестирование

Jest - самый популярный фреймворк для тестирования (в основном юнит-тесты).
React Testing Library - самая популярная библиотека для интеграционного тестирования.
Cypress - самый популярный инструмент для e2e-тестирвания.
Storybook - самый популярный инструмент для тестирования и документации интерфейса.

🔶 4. Workflow

Trunk Based Development - самая распространенная модель разработки, основанная на Git. Для Continuous Integration используются GitHub Actions. Схема довольно простая:

- новая ветка создается от главной
- код пушится в репозиторий
- открывается пулл-реквест
- запускаются все проверки (линтер, проверка типов, тесты)
- проводится код-ревью
- ветка мержится в главную

🟢 Дорожная карта

В заключение автор предлагает "дорожную карту" для погружения в React-экосистему:

1. Разобраться в Trunk Based Development.
2. Начать использовать Next.js.
3. (Опционально) Изучить TypeScript.
4. Использовать ESLint и Prettier.
5. Разобраться в styled-components или MUI для стилизации.
6. Писать тесты с помощью Cypress.
7. (Опционально) Redux.
8. (Опционально) Storybook.

#ссылки #тестирование #стили #инструменты
👍1
React Router. Навигация

Link

Роут указывается в пропе to. Допускаются "относительные" ссылки (у которых в начале нет /), они работают относительно текущего роута (все как у обычных ссылок).

По умолчанию смена роута происходит без перезагрузки страницы, но это поведение можно отменить с помощью пропа reloadDocument (только зачем?).

NavLink

Навигационная ссылка с состоянием "активности". Если роут такой ссылки соответствует текущему роуту приложения, она помечается классом active.

Кроме того, в атрибут style и в атрибут className элемента NavLink можно передать функцию. В качестве параметра она получает объект с полем isActive. Так можно устанавливать динамические стили.

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

Примеры: https://codesandbox.io/s/navlink-react-junior-8g1xen

Кроме того, есть проп end, который убирает активность ссылки, если активен дочерний по отношению к ней роут.
Например, у нас есть ссылка, ведущая на роут /catalog, а текущий активный роут /catalog/pizza. По умолчанию ссылка будет активна, но проп end может это изменить.

Navigate

Это способ управлять роутингом прямо из JSX-разметки, без JS-кода.

Если компонент Navigate рендерится, то происходит изменение роута. То есть он всегда используется с некоторым условием. Под капотом у него используется хук useNavigate, пропсы соответствуют параметрам этого хука (to, replace).

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

Мой вариант: https://codesandbox.io/s/navigate-react-junior-mrp48r?file=/src/pages/Login.js

У нас есть два роута, индексный с формой авторизации и /account. При отправке формы происходит базовая валидация полей, затем данные отправляются на сервер. Если пользователь успешно авторизован, то мы рендерим компонент Navigate с пропом to=/account - происходит переход на страницу Личного кабинета.

#роутинг #примерыкода
React Router. Outlet

Компонент Outlet нужен, усли в приложении есть вложенные роуты. Он используется в родительском роуте в том месте, где нужно вывести контент дочернего роута. Это аналог пропа children для роутов.

https://codesandbox.io/s/outlet-react-junior-d08y8s?file=/src/App.js

Например, есть роут /profile, который представляет личный кабинет пользователя. С ним связан компонент Profile, который рендерит общую информацию о пользователе, а также вкладки Заказы и Баллы лояльности. Каждая вкладка - это отдельный дочерний роут - /profile/orders и profile/loyalty, с каждым из которых связан свой компонент.

Чтобы дочерние роуты выводились, нужно вставить Outlet в нужном месте компонента Profile.

Контекст

Родительский компонент может передавать в дочерние роуты какие-либо данные через проп context элемента Outlet. Таким образом можно поднять состояние из дочерних роутов в родительский. В примере так передается количество баллов лояльности.

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

#роутинг #примерыкода
React Router. Вспомогательные функции

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

Их можно найти в документации на страничке с описанием API: https://reactrouter.com/docs/en/v6/api#api-reference

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

#документация #роутинг
React Router. Глубокое погружение

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

В документации есть отдельный раздел Основные концепции для более подробного изучения React Router. Посмотрим на него одним глазом.

Прежде всего здесь приведены определения для всех терминов (Location, History Stack, Match и пр.): . Полезно начать именно с них, чтобы правильно воспринимать информацию.

Основные составляющие процесса маршрутизации:

- подписка и манипуляции с History Stack (история навигации пользователя)
- матчинг (сопоставление) урла и роутов
- рендеринг активных роутов

История навигации

В браузере есть объект window.history - история навигации пользователя. Это массив урлов, на которые мы переходим. Благодаря истории можно вернуться на предыдущую просмотренную страницу (кнопка Назад).

React Router позволяет изменять историю навигации программно, без перезагрузок страницы и отправки запросов на сервер. Он использует собственный объект history, чтобы отслеживать все изменения.

Для представления текущего урла (window.location) также используется собственная реализация location, более простая и удобная. (Ее можно получить из хука useLocation.)

Для измененения истории навигации предназначены компоненты Link, NavLink, Navigate и хук useNavigate.

Для доступа к текущему урлу и его параметрам - хуки useLocation, useParams, useSearchParams.

Сопоставление роутов

В начале работы React Router составляет конфиг роутинга (route config), который по сути представляет собой просто дерево роутов, созданных с помощью Routes и Route.

Создать такой конфиг можно программно с помощью хука useRoutes (он используется под капотом).

Текущий урл сравнивается со всеми существующими роутами, чтобы найти подходящие. Для каждого подходящего роута создается объет match с информацией о роуте, а также значениями динамических параметров, если они есть.

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

Роуты без путей

Для некоторых роутов не указывается проп path, и они обрабатываются по особым правилам. Это, например, индексные роуты (рендерятся при точном совпадении родительского роута), а также layout-роуты, которые содержат общую разметку для вложенных роутов, но сами по сути роутами не являются.

Рендеринг

Первый роут из массива matches рендерится автоматически, а чтобы продолжить рендеринг нужно использовать компонент Outlet. По сути он принимает массив оставшихся роутов и рендерит первый из них. Соответственно, если в массиве есть еще роуты, то нужны еще Outlet - по одному на каждый уровень вложенности.

Компонент Routes использует Outlet под капотом, чтобы автоматически выводить совпавший роут первого уровня.

Общая схема работы

1. Мы пишем код приложения с компонентами Routes и Route и оборачиваем все в BrowserRouter.
2. BrowserRouter создает объект истории навигации (history), подписывается на его изменения и устанавливает начальный урл (location).
3. Routes рекурсивно обходит своих потомков и создает конфиг роутинга (route config), находит роуты, совпадающие с текущим урлом, собирает все вложенные роуты в массив matches и рендерит первый роут из этого массива.
4. Вы вручную рендерите остальные совпавшие вложенные роуты, используя в нужных местах родительских компонентов Outlet. Каждый Outlet рендерит один следующий роут.
5. Пользователь кликает по компоненту Link.
6. Link вызывает функцию navigate, обращаясь к объекту history.
7. Объект history изменяет урл и оповещает BrowserRouter.
8. BrowserRouter перерендеривается.

#документация #роутинг #подкапотом
React Router. Аутентификация

Пример из документации: https://stackblitz.com/github/remix-run/react-router/tree/main/examples/auth?file=src%2FApp.tsx

Структура приложения

Есть открытая страница PublicPage, доступная по пути /. И есть закрытая страница ProtectedPage, которая должна открываться по пути /protected, но только для авторизованных пользователей. Если пользователь не авторизован, должна открываться форма авторизации.

Создаем три роута (Route): для открытой страницы, для закрытой страницы и для формы авторизации (/login).

Контекст для хранения состояния

Для хранения состояния авторизации используется контекст AuthContext, созданный с помощью метода React.createContext.

Контекст содержит актуальное состояние, а также методы для авторизации и разлогинивания.

Все приложение оборачивается в AuthContext.Provider, а для доступа к контексту используется кастомный хук useAuth, который под капотом использует встроенный хук useContext.

Компонент-обертка для компонентов с закрытым доступом

Создаем вспомогательный компонент RequireAuth. Он оборачивает контент закрытой страницы (ProtectedPage) и должен рендерить его только в том случае, если юзер авторизован.

Этот компонент получает доступ к контексту (через хук useAuth) и узнает текущий статус авторизации. Если пользователь авторизован, то компонент просто рендерит своих потомков (props.children). В противном случае происходит перенаправление на роут /login с помощью компонента Navigate.

У компонента Navigate указывается проп state. Это дополнительные данные, которые связаны с location, но не отображаются в урле. Их можно будет получить из хука useLocation. Этот прием используется, чтобы сохранить страницу, с которой произошел переход.

Кроме того, есть атрибут replace. Он указывает, что урл, на который происходит переход, должен заменить текущий урл в истории навигации.

Форма авторизации

Когда пользователь заполняет и отправляет форму, компонент LoginPage вызывает метод авторизации (из контекста). Если авторизация прошла удачно, происходит переадресация с помощью хука useNavigate - или на страницу, на которую изначально пытались перейти (закрытая страница), если она есть в location.state, или просто на главную страницу приложения.

#документация #роутинг #примерыкода
React Router. Кастомная ссылка

https://stackblitz.com/github/remix-run/react-router/tree/main/examples/custom-link?file=src/App.tsx

Пример создания собственного аналога NavLink - ссылки на роут, которая знает, когда она активна.

Для определения совпадения с текущим роутом используется хук useMatch.

#документация #роутинг #примерыкода
Глубокое погружение в код React. Часть 1. Вводная

Первая часть из серии статей, посвященных разбору кодовой базы React (англ.): https://dev.to/fromaline/deep-dive-into-react-codebase-ep1-prerequisites-33ak

Это вводная часть, которая рассказывает:

- почему React вообще появился (потому что команда разработчиков из Facebook создала сложное приложение с динамическими данными и не смогла справиться с каскадными изменениями интерфейса)
- какова основная идея React (у тебя есть код, который описывает, что должно делать приложение с определенным набором данных. Если данные изменятся, нужно просто перезапустить этот же самый код)
- и как устроен монорепозиторий React (ядро React Core, несколько рендереров для разных сред выполнения и согласователь Fiber Reconciler)

#ссылки #подкапотом
React Router. Lazy loading

https://stackblitz.com/github/remix-run/react-router/tree/main/examples/lazy-loading?file=src/App.tsx

Пример ленивой загрузки компонентов для роутов. Ничего особенного, обычные "ленивые компоненты" с использованием React.lazy для загрузки и React.Suspense для отображения с фоллбэком.

#документация #роутинг #примерыкода #ленивыекомпоненты
Location State

В примере с аутентификацией использовалось некое "состояние Location", чтобы сохранить, на какую страницу пользователь хотел попасть, когда открылась форма авторизации. Разберемся с ним чуть подробнее.

У объекта window.history в браузере есть метод pushState(), который мы можем использовать для изменения текущего урла. Казалось бы, при чем тут state, мы же просто добавляем в историю новую запись.

Однако в сигнатуре этого метода три параметра, и урл - последний из них и необязательный. Первым идет state object - объект состояния, в который можно записать все, что угодно. Таким образом, в истории хранится именно состояние, какие-то данные, а урл может и не меняться.

Получить текущее состояние можно из window.history.state.

React Router позволяет удобно пользоваться этой фишкой прямо из объекта location, таким образом состояние привязывается к местоположению, а не к истории.

Чтобы установить state для location, можно использовать проп state компонента Link. В него можно установить любые данные. Также state можно передать в функцию navigate, полученную из хука useNavigate.

Чтобы получить текущий state, нужно использовать хук useLocation. Он возвращает объект location с полем location.state.

Кейсы для использования:

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

#роутинг #документация #паттерны