React Junior
207 subscribers
37 photos
462 links
Изучение React с нуля
加入频道
Изучаете ли вы код различных опенсорсных проектов (библиотек/инструментов)?
Anonymous Poll
13%
Да, часто это делаю
58%
Изредка
29%
Нет, не люблю разбираться в чужом коде
👍2
Typescript. Утилиты. Часть 4 (Uppercase, Lowercase, Capitalize, Uncapitalize)

Первая часть (Readonly, Required, Partial): https://yangx.top/react_junior/413
Вторая часть (Exclude, Extract, NonNullable): https://yangx.top/react_junior/429
Третья часть (Parameters, ReturnType): https://yangx.top/react_junior/430

В этот раз 4 очень простые утилиты, которые имеют дело с регистром символов:

- Uppercase
- Lowercase
- Capitalize
- Uncapitalize

#typescript
🔥2
TypeScript. Ключевое слово infer

Весь вечер пытаюсь разобраться с ключевым словом infer в TypeScript 🙂 Не сказать, что концепция самая очевидная, но вроде и не чрезмерно сложная, если я, конечно, все правильно понимаю.

Итак, infer может "выводить" один тип на основании другого. Использовать это ключевое слово можно только в условных конструкциях вместе с extend. Выведенный тип затем можно использовать, например, вернуть из условной конструкции.

Подробнее об условных типах: https://yangx.top/react_junior/431

Самый понятный для меня (но вероятно не самый популярный) пример использования infer - на приложенном скрине (взято со StackOverflow).

Утилита UnpackArrayType получает обобщенный тип T.
Затем ставится условие:


T extends (infer R)[]


Эта конструкция буквально означает, "можно ли представить T в виде массива элементов какого-нибудь типа R". При этом тип R буквально "выводится" из типа T с помощью infer. Если T равно number[], то R будет равно number.

Если условие получилось выполнить, возвращается свежевыведенный тип R.

Неплохой разбор infer есть в статье Understanding infer in TypeScript (англ.)

Там автор начинает с более простых концепций: типа never, оператора extends, объединений, а затем переходит к работе с функциями и собственно ключевому слову infer.

К слову, именно infer лежит в основе работы утилиты ReturnType.

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

#ссылки #typescript #подкапотом #infer
👍5
Forwarded from Cat in Web
Создание модальных окон в React: от основ до продвинутого уровня

Статья (англ.): https://medium.com/tinyso/how-to-create-a-modal-component-in-react-from-basic-to-advanced-a3357a2a716a

Статья пошагово описывает процесс создания React-компонента модального окна: от разметки до поведения.

Для управления видимостью используется проп show. Кроме того компонент отслеживает свое закрытие и вызывает функцию onClose.

Обрабатывается закрытие при клике на кнопку Close, подложку, а также по нажатию клавиши Escape.

Текст заголовка и содержимое модального окна передаются динамически через пропсы (`title` и `children`).

Появление и исчезновение модального окна сопровождается анимацией с использованием компонента CSSTransition из пакета react-transition-group (в этот пакет вынесена вся transition-функциональность React).

И наконец, модальное окно рендерится вне контейнера с помощью портала (`ReactDOM.createPortal`).

#react #interface
👍4🔥1
Кастомный хук useDebounce

Статья (англ.): https://blog.logrocket.com/create-custom-debounce-hook-react/

В статье рассматривается решение популярной задачи фронтенда: динамический поиск и подгрузка данных при вводе пользователя (например, поле поиска с автодополнением).

Чтобы не отправлять запрос при вводе каждой буквы, мы используем технику debouncing - метод выполняется только через некоторое время после последнего вызова. Например, пользователь быстро ввел несколько символов и остановился на пару секунд - хорошее время для выполнения запроса.

В статье создается кастомный React-хук useDebounce, который на вход получает постоянно меняющееся значение (состояние поля ввода), а также значение задержки в миллисекундах. Хук возвращает debounced-значение, которое будет обновляться только после задержки.

Для реализации логики задержки используется встроенный хук useEffect с функциональностью сброса эффекта.
Хук планирует обновление debounced-значения через указанное время.

Эффект сбрасывается при каждом изменении основного состояния - значения поля ввода. То есть если исходное значение изменится раньше, то обновление debounced-значения будет отложено.

Компонент, который использует этот хук, полагается на изменение debounced-значения - когда оно изменяеется, осуществляет запрос к серверу.

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

Создается контроллер и сохраняется в ref, а его свойство signal передается в запрос.
При отправке нового запроса, старый прерывается (метод `controller.abort()`).

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

AbortController на MDN: https://developer.mozilla.org/ru/docs/Web/API/AbortController
Прерывание fetch-запроса на Learn JavaScript: https://learn.javascript.ru/fetch-abort

На самом деле все просто, нужно просто в метод fetch передать в настройках signal.

#ссылки #хуки #примерыкода
👍2🔥1
Статья (англ.): https://levelup.gitconnected.com/using-typescript-infer-like-a-pro-f30ab8ab41c7

Еще немного про infer (начало здесь)

В статье приводится очень хорошее пошаговое объяснение того, как работает это ключевое слово.

Infer буквально распаковывает тип и позволяет вывести из него другой тип.

Рассматривается тот же пример с распаковкой массива и получением типа элемента (только подробнее и с анимацией).
Кроме того есть примеры с распаковкой аргументов и возвращаемого значения функций (так работает под капотом утилита ReturnType) и распаковкой ключей объекта.

Важно помнить, что infer может использоваться только в условных типах (`extends`) и после "захвата" доступен только в true-части выражения.

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

В конце задачка, которая сломала мой мозг 🤯

#typescript #infer
👍4
TypeScript. Шаблонные литералы

Статья (англ.): https://javascript.plainenglish.io/how-to-use-typescript-template-literal-types-like-a-pro-2e02a7db0bac

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

type Alignment = 'start' | 'end';
type Side = 'top' | 'right' | 'bottom' | 'left';
type AlignedPlacement = `${Side}-${Alignment}`;


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

В шаблонных строках можно также использовать утилиты, работающие со строками (Uppercase, Lowercase, Capitalize, Uncapitalize).
Также их можно использовать в условных типах в сочетании с ключевым словом infer для создания очень мощных условий.

В статье разобрано использование шаблонных строк для Key Remapping (переименования ключей в сопоставимых типах).

А в самом конце есть прекрасный пример рекурсивной работы с типами.

#typescript
🔥3👍2
Typescript. Утилиты. Часть 5 (Pick, Omit)

Первая часть (Readonly, Required, Partial): https://yangx.top/react_junior/413
Вторая часть (Exclude, Extract, NonNullable): https://yangx.top/react_junior/429
Третья часть (Parameters, ReturnType): https://yangx.top/react_junior/430
Четвертая часть (Uppercase, Lowercase, Capitalize, Uncapitalize): https://yangx.top/react_junior/435

Утилита Pick получает два параметра: исходный тип и набор ключей. Результат работы - новый тип на основе исходного, в который входят только указанные ключи.

Эта утилита похожа на Mapped Types, только Mapped Types берут полный набор ключей из исходного типа, а для Pick набор ключей заранее указан.

Omit, соответственно, работает наоборот, берет все ключи, кроме указанных. Под капотом использует Pick и Exclude, чтобы получить набор нужных для типа ключей.

#typescript
👍1🔥1
У вас в данный момент есть активные пет-проекты?
Anonymous Poll
31%
Один
15%
Больше одного
46%
Нет, не хватает времени/сил
8%
Нет, нет желания
TypeScript. 15 самых популярных утилит

Статья (англ.): https://javascript.plainenglish.io/15-utility-types-that-every-typescript-developer-should-know-6cf121d4047c

С большинством из перечисленных в статье утилит мы уже знакомы.

Partial, Required, Readonly

Функциональность этих утилит разбирали здесь: https://yangx.top/react_junior/413
А подкапотную реализацию здесь (статья о Mapped Types): https://yangx.top/react_junior/428
Для перебора ключей используется конструкция P in keyof T.

Exclude, Extract, NonNullable

Функциональность тут: https://yangx.top/react_junior/429
Реализованы на условных типах: https://yangx.top/react_junior/431
Члены одного набора типов сопоставляются с членами второго набора с помощью конструкции T extends U ? X : Y

Pick, Omit

Функциональность и реализация тут: https://yangx.top/react_junior/442
Напоминают Mapped Types.

Parameters, ReturnType

Функциональность тут: https://yangx.top/react_junior/430
В реализации используется ключевое слово infer https://yangx.top/react_junior/439, чтобы вытащить нужные типы из полученного типа функции.

Uppercase, Lowercase, Capitalize, Uncapitalize

Функциональность здесь: https://yangx.top/react_junior/435

Record

С этой утилитой мы еще не встречались.

Она принимает два обобщенных типа: набор ключей Keys и тип значений Type. Из них формируется новый тип, в котором есть все ключи из Keys и каждому из них соответствует значение типа Type.

Условно это выглядит так:


type Keys = 101 | 102 | 103; // набор ключей
type User = { name: string; age: number }; // тип значений

// результат
type Record = {
101: User,
102: User,
103: User
}


#typescript
👍3🔥2
10 вещей, которые нужно знать о классах в TypeScript

Статья (англ.): https://levelup.gitconnected.com/10-things-you-need-to-know-about-typescript-classes-f58c57869266

Достаточно полный справочник по классам в TypeScript.

Первые пункты простые:

1. Статические поля и поля класса
2. Геттеры и сеттеры
3. Наследование классов (и реализация интерфейсов)
4. Абстрактные классы
5. Модификаторы доступа (и их сочетание с ECMAScript Private Fields)
6. Class Expressions
7. Использование дженериков в классах (https://yangx.top/react_junior/405)

Дальше посложнее: про конструкторы (и абстрактные конструкторы) и про использование в качестве типа самого класса и typeof Class. Это все пока не очень понятно, как использовать.

Но если что тип для функции-конструктора на скрине.

#typescript
👍3🔥2
Думаю, в общих чертах с TypeScript разобрались. Следующая тема для изучения - серверный рендеринг.
Пока разбираюсь в основах, в ближайшее время начнем :)
👍4🔥3
Рендеринг на стороне сервера

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

В чем принципиальная разница?

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

‼️ Какие подходы есть?

1. Просто оставить ключевые страницы сайта статическими (никаких вам SPA).

2. Делать SPA, но во время сборки генерировать статические страницы для него (библиотека react-snaphot, потом взглянем на нее). Очевидно, эти страницы будут использоваться как точки входа с хорошим SEO, а затем вступит в дело механизм SPA. Но тут есть вопросы с разными динамическими данными (апи, данные, передаваемые в урле)

3. Использовать технологии для полноценного серверного рендеринга (часть кода будет выполняться на сервере, например, Next.js).
Тут тоже есть два подхода:
- SSG (статическая генерация сайта) - что-то очень похожее на пункт 2, но покруче. Статические страницы рендерятся при сборке проекта. Доступны даже динамические урлы.
- SSR (рендеринг на стороне сервера) - что-то очень похожее на старый-добрый рендеринг на сервере, когда рендер происходит при каждом запросе.

Основное внимание мы уделим, конечно, Next.js. Также мельком глянем на react-snapshot.

#серверныйрендеринг
🔥4👍1
Next.js. Начало

Next.js - это инструмент, который должен нам помочь превратить обычное SPA на React в изоморфное приложение. То есть такое приложение, которое сначала выполнится на сервере и сгенерирует нам статические HTML-странички. А затем эти странички в браузере пользователя пройдут через процедуру гидратации и превратятся в нормальное SPA с роутингом и прочими плюшками.

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

При этом в отличие от "классического" серверного рендеринга (как на PHP-сайтах), наше приложение, по идее, не будет иметь дела с данными напрямую, даже на сервере. Оно должно обращаться к некому API-серверу, чтобы получать то, что нужно в виде JSON.

В этот раз начнем не с документации, а с видео-курса, возможно, так будет попроще.

Курс (от Владилена Минина) здесь: https://www.youtube.com/watch?v=_EOrSmjdOZQ
продолжительность 2,5 часа

Разворачиваем проект

Для быстрого разворачивания проекта на Next.js используем утилиту create-next-app (как create-react-app). Получаем шаблонный Next-проект.

Что тут есть интересного:

- папка pages, в которой будут лежать все наши странички. Тут уже лежат файлы index.tsx, api/hello.ts и пара файлов, у которых имена начинаются с нижнего подчеркивания (вероятно, они не превратятся в отдельные страницы)

- папка public - очевидно, публичные ресурсы, которые будут скопированы в собранный проект

- папка styles с файлами global.css и Home.module.css. Видимо, это система организации стилей по умолчанию. Потом посмотрим, как прикрутить что-нибудь другое

- в package.json есть скрипты dev, start и build.

Если запустить npm run dev, развернется локальный сервер с демо-страницей.

Никакого App.tsx или чего-то подобного нет, точка входа в проект, очевидно, pages/index.tsx.

#серверныйрендеринг #nextjs
👍3🔥1
Next.js. Роутинг на файлах

Роутинг в Next.js основан на файлах. Каждый файл в папке pages это отдельная страничка нашего сайта, к которой можно получить доступ по ее имени.

Например, файл pages/index.tsx - это корневая страница нашего проекта, в данном случае localhost:3000/.
Файл pages/posts.tsx - это страница localhost:3000/posts/.

В каждом таком файле находится самый обычный React-компонент (экспортируется по умолчанию).

Страницы можно вкладывать в папки, например, pages/about/contacts.tsx. Этот компонент будет доступен по адресу /about/contacts/.

#серверныйрендеринг #nextjs
👍3
Чтобы убедиться, что это не обычное SPA-приложение, а именно заранее отрендеренный на сервере документ, можно открыть код страницы или посмотреть первый запрос в панели Network - там будет HTML-документ с уже вставленным текстом. Получается, что компонент отрендерился на сервере и пришел в браузер уже в готовом виде.

Кроме того тут можно увидеть скрипт с id __NEXT_DATA_, который содержит какой-то JSON. Предположительно, это данные для гидратации приложения на клиенте.

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

Next позволяет работать не только с простыми роутами типа / или /about/contacts, но и с динамическими фрагментами. Например, это могут быть страницы статей post/1, post/2 и так далее.

Динамическая часть такого роута заключается в квадратные скобки: pages/post/[id].tsx.

Чтобы получить значение динамических параметров, нужно использовать хук роутера - useRouter из пакета next/router.

const router = useRouter();
console.log(router);


Параметры находятся в поле router.query.

Теперь можно перейти на страницу http://localhost:3000/post/1.

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

#серверныйрендеринг #nextjs
👍3🔥2
Next.js. Клиентский роутинг

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

Для этого Next предоставляет компонент Link, который работает так же, как и Link из React, только при выполнении на сервере он превращается в обычную HTML-ссылку.

Адрес ссылки указывается в пропе href.

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

Демо: https://codesandbox.io/p/sandbox/stupefied-sutherland-r0xd40?selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A4%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A4%7D%5D&file=%2Fpages%2Findex.tsx

#серверныйрендеринг #nextjs #примерыкода
👍3🔥2
Next.js. Мета-данные страницы

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

Next предоставляет компонент Head, в который можно поместить любые теги, которые должны быть в секции head страницы (title, meta-теги). Размещать этот компонент можно в любом месте страницы.

#серверныйрендеринг #nextjs
🔥3👍2
Компоненты/лейауты, которые переиспользуются на разных страницах, нужно вынести за пределы папки pages, так как в pages должны лежать именно страницы.

#nextjs #серверныйрендеринг #примерыкода
👍3🔥2