Создание собственных ошибок в приложении
С ростом приложения может быть полезно создавать собственные ошибка для удобства их обработки, лебага и логирования. В этом посте поговорим о стандартных способах как это можно сделать.
Обычно ошибки выбрасываются следующим образом:
Это удобно и быстро, но с ростом приложения можно оптимизировать и это. Для этого нужно создать собственный класс ошибки:
Обратите внимание, что нам нужно обязательно унаследовать собственную ошибку от стандартного класса
Далее разберем пример создания ошибок, которые могут возникнуть в работе с
Тут мы создаём две ошибки, которые далее сможем использовать в нашем приложении. Этап с объединением под
Кстати, чтобы обработать конкретную ошибку определенным способом, используется следующая конструкция:
Конструкция со
На этом всё, что я хотел описать в этой теме. Надеюсь, что это было полезно. Поддержите реакциями)
Спасибо за прочтение, это важно для меня ❤️
#web #javascript #theory #data
С ростом приложения может быть полезно создавать собственные ошибка для удобства их обработки, лебага и логирования. В этом посте поговорим о стандартных способах как это можно сделать.
Обычно ошибки выбрасываются следующим образом:
throw Error("Ошибка сервера")
Это удобно и быстро, но с ростом приложения можно оптимизировать и это. Для этого нужно создать собственный класс ошибки:
class CustomError extends Error {
constructor(message: string) {
super(message);
this.name = 'CustomError';
}
}
Обратите внимание, что нам нужно обязательно унаследовать собственную ошибку от стандартного класса
Error
и вызвать конструктор родительского класса через super
— это необходимые шаги для правильной инициализации собственной ошибки. this.name
устанавливается для того, чтобы ошибку в логах было проще идентифицировать. Это очень полезно, но не обязательно.Далее разберем пример создания ошибок, которые могут возникнуть в работе с
API
:class NullableRequestParameter extends Error {
constructor(message = 'Required req param is nullable') {
super(message)
this.name = 'NullableRequestParameter'
}
}
class Unauthorized extends Error {
constructor(message = 'User is unauthorized') {
super(message)
this.name = 'Unauthorized'
this.code = 401
}
}
export const RestServiceError = {
NullableRequestParameter,
Unauthorized
} as const
// где-то выбросим нужную нам ошибку
throw RestServiceError.Unauthorized()
Тут мы создаём две ошибки, которые далее сможем использовать в нашем приложении. Этап с объединением под
RestServiceError
можно опустить, это уже мой собственный код стайл. Люблю объединять общие сущности под единым началом.Кстати, чтобы обработать конкретную ошибку определенным способом, используется следующая конструкция:
try {
// код, где может быть ошибка
} catch (error) {
switch (true) {
case error instanceof RestServiceError.Unauthorized:
// обработка ошибки Unauthorized
break;
case error instanceof RestServiceError.NullableRequestParameter:
// обработка ошибки NullableRequestParameter
break;
default:
// обработка всех непредвиденных ошибок
}
}
Конструкция со
switch (true)
является более предпочтительной из-за читаемости и расширяемости, хотя можно решить ту же задачу просто через if else
.На этом всё, что я хотел описать в этой теме. Надеюсь, что это было полезно. Поддержите реакциями)
Спасибо за прочтение, это важно для меня ❤️
#web #javascript #theory #data
❤26👍9🔥2🐳2🍌1
Попробуем устроить интерактив 👍
Предлагаю собрать ссылки на ваши пет-проекты. Я посмотрю их, а самые частые и популярные ошибки среди всех проектов я разберу в формате постов в этом канале
Для начала ограничимся следующим:
— открытый репозиторий на площадке типа GitHub
— проект на JavaScript/TypeScript
— React или проект без использования фреймворка/библиотек
Можете поделиться постом с друзьями, участвовать могут все желающие. Анкета анонимная, но есть возможность оставить свою телегу, если хотите
Кстати, можно отправить несколько проектов на рассмотрение, для этого просто заполните форму несколько раз
🟢 Google форма для участия
@prog_way_blog
Предлагаю собрать ссылки на ваши пет-проекты. Я посмотрю их, а самые частые и популярные ошибки среди всех проектов я разберу в формате постов в этом канале
Для начала ограничимся следующим:
— открытый репозиторий на площадке типа GitHub
— проект на JavaScript/TypeScript
— React или проект без использования фреймворка/библиотек
Можете поделиться постом с друзьями, участвовать могут все желающие. Анкета анонимная, но есть возможность оставить свою телегу, если хотите
Кстати, можно отправить несколько проектов на рассмотрение, для этого просто заполните форму несколько раз
@prog_way_blog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥21👍3🐳2❤1
Схлопывание отступов CSS
Схлопывание отступов — механизм в CSS, при котором верхние и нижние внешние отступы двух соседних элементов могут объединяться в один отступ, если они расположены друг над другом. Это поведение может вызывать лишнее недопонимание.
Если рассмотреть ситуацию на фото, прикрепленное к посту, то можно увидеть два блока, верхний из которых имеет
Чтобы избежать схлопывания, достаточно использовать связку из разных отступов, например
Такой способ гораздо более надёжный и контролируемый, а также читается легче.
Спасибо за прочтение, это важно для меня ❤️
#web #theory
Схлопывание отступов — механизм в CSS, при котором верхние и нижние внешние отступы двух соседних элементов могут объединяться в один отступ, если они расположены друг над другом. Это поведение может вызывать лишнее недопонимание.
Если рассмотреть ситуацию на фото, прикрепленное к посту, то можно увидеть два блока, верхний из которых имеет
margin-bottom: 100px
, а нижний — margin-top: 70px
. Казалось бы, очевидно, что итоговый отступ между блоками будет 170px
, но на самом деле это не так. В таком случае, отступы объединятся и будет выбрано и применено максимальное значение из двух: max(100px, 70px) => 100px
.Чтобы избежать схлопывания, достаточно использовать связку из разных отступов, например
margin
для верхнего элемента и padding
для нижнего. Но такой способ я считаю всё таки костыльным. Гораздо лучше объединить два блока в родительский flex
контейнер и использовать свойство gap
для задания отступов между всеми элементами flex
группы:<div class="container">
<div>Верхний</div>
<div>Нижний</div>
</div>
.container {
display: flex;
flex-direction: column;
gap: 170px;
}
Такой способ гораздо более надёжный и контролируемый, а также читается легче.
Спасибо за прочтение, это важно для меня ❤️
#web #theory
❤37👍12🐳5🔥2🍌1🤝1
Метод массива with
Если разбирать сразу же на примере, то выглядит это следующим образом:
Первым аргументом метод
Аналогом подобного метода можно считать прямую замену элемента при обращении по его индексу, только метод
Чтобы обойти мутацию, нам необходимо создавать отдельно копию изначального массива, а это неудобно. Метод
Честно сказать, не смог придумать невероятно удобных кейсов применения этого метода, кроме редакса. На собесе ответить хватит и ладно. Есть и есть, чего бубнеть то.
#web #theory
with
— ещё один новый метод массива из спецификации ECMAScript 2023, который позволяет удобно решить одну крайне специфичную задачу — изменить массив и создать его копию.Если разбирать сразу же на примере, то выглядит это следующим образом:
const nums = [1, 2, 3, 4]
const newNums = nums.with(1, 'string')
console.log(newNums) // [1, 'string', 3, 4]
Первым аргументом метод
with
принимает индекс, на котором будет произведена замена, а вторым — новое значение.Аналогом подобного метода можно считать прямую замену элемента при обращении по его индексу, только метод
with
не мутирует исходный массив:const nums = [1, 2, 3, 4]
nums[1] = 'string'
console.log(nums) // [1, 'string', 3, 4]
Чтобы обойти мутацию, нам необходимо создавать отдельно копию изначального массива, а это неудобно. Метод
with
автоматически создаст копию за нас, что может сыграть на руку, например, в чистом redux
.Честно сказать, не смог придумать невероятно удобных кейсов применения этого метода, кроме редакса. На собесе ответить хватит и ладно. Есть и есть, чего бубнеть то.
#web #theory
👍37🐳10🔥3❤1🍌1
progway — программирование, IT
Попробуем устроить интерактив 👍 Предлагаю собрать ссылки на ваши пет-проекты. Я посмотрю их, а самые частые и популярные ошибки среди всех проектов я разберу в формате постов в этом канале Для начала ограничимся следующим: — открытый репозиторий на площадке…
Было тяжело, но я справился…
Как и обещал пару постов выше, я посмотрел проекты, что вы прислали на ревью. Этим постом я закрываю сбор ссылок, их и так было не мало)
Я просмотрел абсолютно всё, что было прислано, каждый проект.
Что в итоге:
1. Допишу пост с общими замечаниями, которые слишком малы для отдельного поста, и опубликую его где-то через полчаса-час
2. Далее будет 9 отдельных постов с разными темами по ревью. Их буду публиковать по 3 в день, чтобы совсем не заспамить канал
3. Ну и вернёмся к тому контенту, что я публикую обычно
Приз зрительской симпатии от меня получает приложение для подготовки в ЕГЭ. Проект объективно простенький, но я в какой-то момент залип и сидел буковки тыкал. Успел накликать больше 100 слов, пока вспомнил, а зачем я там, собственно)
Что ещё важно
Я создал чат канала. Кто не знает, каналу уже сильно больше 3 лет и всё это время он существовал без публичной обратной связи — со мной можно было связаться только в личку. Сейчас же я решил создать чат, что для меня шаг достаточно важный:
1. Идея с ревью была прикольная, но я понимаю, что дать какую-то качественную обратную связь в формате постов очень тяжело. Поэтому, я надеюсь, чатик станет адекватным местом для дискуссий
2. Под постами появятся комментарии и у вас появится великолепная возможность закидать меня помидорами 💔
Ссылка на чат
Спасибо за участие, это важно для меня
@prog_way_blog — #blog #review
Как и обещал пару постов выше, я посмотрел проекты, что вы прислали на ревью. Этим постом я закрываю сбор ссылок, их и так было не мало)
Я просмотрел абсолютно всё, что было прислано, каждый проект.
Что в итоге:
1. Допишу пост с общими замечаниями, которые слишком малы для отдельного поста, и опубликую его где-то через полчаса-час
2. Далее будет 9 отдельных постов с разными темами по ревью. Их буду публиковать по 3 в день, чтобы совсем не заспамить канал
3. Ну и вернёмся к тому контенту, что я публикую обычно
Приз зрительской симпатии от меня получает приложение для подготовки в ЕГЭ. Проект объективно простенький, но я в какой-то момент залип и сидел буковки тыкал. Успел накликать больше 100 слов, пока вспомнил, а зачем я там, собственно)
Что ещё важно
Я создал чат канала. Кто не знает, каналу уже сильно больше 3 лет и всё это время он существовал без публичной обратной связи — со мной можно было связаться только в личку. Сейчас же я решил создать чат, что для меня шаг достаточно важный:
1. Идея с ревью была прикольная, но я понимаю, что дать какую-то качественную обратную связь в формате постов очень тяжело. Поэтому, я надеюсь, чатик станет адекватным местом для дискуссий
2. Под постами появятся комментарии и у вас появится великолепная возможность закидать меня помидорами 💔
Ссылка на чат
Спасибо за участие, это важно для меня
@prog_way_blog — #blog #review
❤16🔥4🐳4👍1🍌1
Общие комментарии
1. Используйте TypeScript, на современном рынке даже джуну уже не достаточно примитивных знаний TS — большинство компаний требуют хороший опыт работы с типами, понимание дженериков и прочих не самых примитивных тем
2. Выносите хотя бы ёмкие константы куда-то из файла компонента, чтобы до самого компонента не приходилось листать 100+ строк при открытии файла
3. Выносите из компонента все независимые от его состояния сущности — в константы, в утилсы и в любое другое подходящее место. Это упростит чтение кода и зафиксирует ссылки
4. Не стесняйтесь создавать свои хуки, это ок. Есть примеры, где вызов
5. Очень много непонятных закомментированных частей кода в некоторых проектах. Комментируете = не надо = удаляете, восстановить всегда можно через гит
6. Используйте
7. Аккуратнее с инлайн стилями. Их можно использовать, но очень аккуратно и в крайних случаях. ИМХО лучше
8. Не используйте классовые компоненты, если в этом нет явной необходимости. Мир функциональных компонентов уже непобедим
9. Не храните ключи и прочие переменные в коде, используйте переменные окружения. Из кода можно легко компрометировать все ваши ключи, тем более проекты лежат в открытом доступе
10. Не нужно оборачивать в
11. Можно смириться с одним тернарным оператором в вёрстке, но когда их в одной конструкции сразу два… три… такое мы рефакторим обычными if-ами)
Отдельные посты по этому ревью будут выходить с завтрашнего дня
@prog_way_blog — чат — #review
1. Используйте TypeScript, на современном рынке даже джуну уже не достаточно примитивных знаний TS — большинство компаний требуют хороший опыт работы с типами, понимание дженериков и прочих не самых примитивных тем
2. Выносите хотя бы ёмкие константы куда-то из файла компонента, чтобы до самого компонента не приходилось листать 100+ строк при открытии файла
3. Выносите из компонента все независимые от его состояния сущности — в константы, в утилсы и в любое другое подходящее место. Это упростит чтение кода и зафиксирует ссылки
4. Не стесняйтесь создавать свои хуки, это ок. Есть примеры, где вызов
useEffect
достигает 50+ строк. Вынесите/разбейте, ничего страшного в этом нет5. Очень много непонятных закомментированных частей кода в некоторых проектах. Комментируете = не надо = удаляете, восстановить всегда можно через гит
6. Используйте
index
файлы для организации импортов, это делает импорты короче и читабельнее, а также позволяет проще управлять интерфейсом части кода. Используя index файл, вы явно определяете что можно импортировать, а что нельзя. Подробнее на доке7. Аккуратнее с инлайн стилями. Их можно использовать, но очень аккуратно и в крайних случаях. ИМХО лучше
!important
поставить, чем инлайнить. Ну а если используйте, то не пишите стили прямо в вёрстке. 99% случаев, которые я видел, не зависят от состояния компонента, так что можно легко создать константу вне компонента и зафиксировать ссылку на объект, что может быть очень полезно и в целом разгрузит вёрстку8. Не используйте классовые компоненты, если в этом нет явной необходимости. Мир функциональных компонентов уже непобедим
9. Не храните ключи и прочие переменные в коде, используйте переменные окружения. Из кода можно легко компрометировать все ваши ключи, тем более проекты лежат в открытом доступе
10. Не нужно оборачивать в
memo
, useMemo
, useCallback
абсолютно всё. В ревью видел много мест, где memo
используется там, где компонент имеет 1 рендер за весь жизненный цикл и без него, а useCallback
скорее замедляет приложением, чем оптимизирует 11. Можно смириться с одним тернарным оператором в вёрстке, но когда их в одной конструкции сразу два… три… такое мы рефакторим обычными if-ами)
Отдельные посты по этому ревью будут выходить с завтрашнего дня
@prog_way_blog — чат — #review
🔥37👍10❤4🐳4🍌1🫡1
Использование gap вместо margin
Начнем комментарии по проектам с популярной ошибки — использование
Почему использовать
1. Легче изменять код — чаще всего отступы везде одинаковые в таких списках. При изменении отступов, проще изменить его в одном месте, чем для каждого компонента вёрстки
2. Более чистый код, отсутствие дублирования стилей
3. Лучше производительность — браузеру куда проще обработать
Что такое свойство gap
Что такое row-gap, column-gap
@prog_way_blog — #web #review
Начнем комментарии по проектам с популярной ошибки — использование
margin
вместо gap
. Посты постараюсь делать покороче, не хочу развозить на это всю ленту.Почему использовать
gap
лучше margin
:1. Легче изменять код — чаще всего отступы везде одинаковые в таких списках. При изменении отступов, проще изменить его в одном месте, чем для каждого компонента вёрстки
2. Более чистый код, отсутствие дублирования стилей
3. Лучше производительность — браузеру куда проще обработать
gap
в структурированной сетке, чем нарисовать для каждого отдельного элемента собственный отступЧто такое свойство gap
Что такое row-gap, column-gap
@prog_way_blog — #web #review
👍26🔥5🐳4❤2🍌1👀1
Файловая структура проекта
Очень важно понимать, что файловая структура — это самый верный помощник разработчика в навигации по проекту.
В некоторых проектах, что прислали на ревью, в файловой структуре бывало достаточно тяжело разобраться. Тут и
Чтобы путаницы не возникало при переходе от проекта к проекту, стоит использовать общепринятые нормы оформления проектов, которые под собой подразумевают в том числе организованную файловую структуру. Для примера, это может быть FSD, который сейчас на пике популярности.
Также стоит руководствоваться просто логикой. Лично для меня не до конца понятно, когда в папку
Компоненты я бы сложил к компонентам, даже если они утилитарные (пример на фото), а валидаторы в сервисы, хотя момент всё таки спорный. Лично я бы сделал что-то типа
Тут
Вызов самого валидатора был бы следующий:
Я люблю такие оргструктуры, это мой код стайл. Кому-то он покажется странным, но его плюсы очевидны:
1. Строгая иерархичность и однозначность расположения валидаторов
2. Простой поиск того, что тебе нужно
3. Красивые импорты
4. Простое управление публичным интерфейсом сущности
Архитектурная методология Feature Slices Design
@prog_way_blog — #review
Очень важно понимать, что файловая структура — это самый верный помощник разработчика в навигации по проекту.
В некоторых проектах, что прислали на ревью, в файловой структуре бывало достаточно тяжело разобраться. Тут и
pages
внутри components
, и другие чудеса. Чтобы путаницы не возникало при переходе от проекта к проекту, стоит использовать общепринятые нормы оформления проектов, которые под собой подразумевают в том числе организованную файловую структуру. Для примера, это может быть FSD, который сейчас на пике популярности.
Также стоит руководствоваться просто логикой. Лично для меня не до конца понятно, когда в папку
utils
складывают компоненты и валидаторы, а константы в папку services
Компоненты я бы сложил к компонентам, даже если они утилитарные (пример на фото), а валидаторы в сервисы, хотя момент всё таки спорный. Лично я бы сделал что-то типа
ValidatorService
и разделил бы его на два дочерних сервиса: InputValidator
и ModelValidator
Тут
InputValidator
отвечал бы, очевидно, за ввод, а ModelValidator
для валидации моделей, например, валидации payload’a из ответа апишки.Вызов самого валидатора был бы следующий:
ValidatorService.InputValidator.email(email)
Я люблю такие оргструктуры, это мой код стайл. Кому-то он покажется странным, но его плюсы очевидны:
1. Строгая иерархичность и однозначность расположения валидаторов
2. Простой поиск того, что тебе нужно
3. Красивые импорты
4. Простое управление публичным интерфейсом сущности
Архитектурная методология Feature Slices Design
@prog_way_blog — #review
👍22🐳6❤2🔥2🍌1
Нейминг файлов
1. Определитесь в каком стиле именуете файлы. В одном проекте не должно существовать файлов
2. Я советовал бы переименовать
3. В названии файлов стоит избегать аббревиатур и сокращений, всегда удивляла мания экономить буквы у разработчиков. Лучше использовать только общепринятые сокращения, например,
@prog_way_blog — #review
1. Определитесь в каком стиле именуете файлы. В одном проекте не должно существовать файлов
MarktetTrends.jsx
, filterSlice.js
, table.hook.jsx
. Если делаем групповой суффикс к файлу, типа *.component.jsx
, то делаем везде. Если используем camelCase
, то везде. Выглядит симпатичнее, искать проще, нет визуальной каши.2. Я советовал бы переименовать
table.hook.jsx
в use-table.hool.jsx
или use-table.jsx
. Вы же знаете, что с use начинаются хуки. В поиске инстинктивно напишете use table
и файл table.hook.jsx
просто не найдёте. Неймингом можно спасти не одну нервную клетку, так же как и убить.3. В названии файлов стоит избегать аббревиатур и сокращений, всегда удивляла мания экономить буквы у разработчиков. Лучше использовать только общепринятые сокращения, например,
http
, чтобы избежать недопониманий@prog_way_blog — #review
👍17🔥4🐳4🍌1
Линтеры
Я мог бы кучу моментов подметить на тему того, что “тут кавычки не те”, а “тут отступы кривые”. Настройте линтер. На подобные комменты в процессе ревью вообще отвлекаться — антипаттерн. Если ревью состоит из того, что вам указывают где какую кавычку лучше поставить, то это бред, а не ревью. Подобные вопросы должны решаться автоматизировано.
Другая проблема — в некоторых проектах есть eslint/prettier, супер, круто, но видно же, что код отформатирован не по ним, а в некоторых местах вообще стоят
@prog_way_blog — #review
Я мог бы кучу моментов подметить на тему того, что “тут кавычки не те”, а “тут отступы кривые”. Настройте линтер. На подобные комменты в процессе ревью вообще отвлекаться — антипаттерн. Если ревью состоит из того, что вам указывают где какую кавычку лучше поставить, то это бред, а не ревью. Подобные вопросы должны решаться автоматизировано.
Другая проблема — в некоторых проектах есть eslint/prettier, супер, круто, но видно же, что код отформатирован не по ним, а в некоторых местах вообще стоят
eslint-disable
комменты. Пожалуйста, помимо закидывания конфиги в проект, убедитесь, что линтер реально работает и форматирует всё так, как ожидается. Ну и eslint-disable
использовать тоже очевидно не нужно) @prog_way_blog — #review
👍16🐳9🔥2🤯2🍌1
Комплексные состояния
Есть такой код:
Как его можно исправить:
Почему я считаю что так лучше:
1. Проще следить за иммутабельностью состояния, так как не нужно постоянно разворачивать
2. Легче контролировать зависимости и сайд эффекты, если на состояние завязывается, например,
3. Визуально в использовании считается легче
5. Нет необходимости создавать ещё какой-то тип
В целом, можно и так оставить то. Работать будет, и даже уже сейчас работает. Но лично мне такое бьет по глазам.
@prog_way_blog —#typescript #web #review
Есть такой код:
const [userData, setUserData] = React.useState<IData>({
identifier: "",
password: "",
});
Как его можно исправить:
const [identifier, setIdentifier] = useState<string>("");
const [password, setPassword] = useState<string>("");
Почему я считаю что так лучше:
1. Проще следить за иммутабельностью состояния, так как не нужно постоянно разворачивать
prev
объект2. Легче контролировать зависимости и сайд эффекты, если на состояние завязывается, например,
useEffect
3. Визуально в использовании считается легче
4. useState
вместо React.useState
, ИМХО приятнее5. Нет необходимости создавать ещё какой-то тип
В целом, можно и так оставить то. Работать будет, и даже уже сейчас работает. Но лично мне такое бьет по глазам.
@prog_way_blog —#typescript #web #review
🔥14🐳6👍2🍌1
Магические числа
Немного магии — не всегда приятно. Есть код:
Как можно сделать:
Как на самом деле нужно сделать:
Так нужно сделать, чтобы не завязываться на число
@prog_way_blog — #review
Немного магии — не всегда приятно. Есть код:
date.setTime(date.getTime() + (365 * 24 * 60 * 60 * 1000));
Как можно сделать:
const MILLISECONDS_PER_YEAR = 365 * 24 * 60 * 60 * 1000;
date.setTime(date.getTime() + MILLISECONDS_PER_YEAR);
Как на самом деле нужно сделать:
const date = new Date();
date.setFullYear(date.getFullYear() + 1);
Так нужно сделать, чтобы не завязываться на число
365
, так как год бывает високосным.@prog_way_blog — #review
👍28🐳3❤2🔥2🍌2🗿2
Ответственность состояния
Есть код:
Как можно было бы сделать:
Ну и в зависимости от
@prog_way_blog — #review
Есть код:
const [isFormSubmited, setFormSubmited] = React.useState({
submited: false,
submitedText: "",
submitedError: "",
submitedColor: "",
});
setFormSubmited({
submited: true,
submitedText: "Вы успешно зарегистрировались!",
submitedError: "",
submitedColor: "#238C47",
});
Как можно было бы сделать:
enum FormState {
Success,
Error,
WaitingForAction
}
const [formState, setFormState] = useState<FormState>(FormState.WaitingForAction);
Ну и в зависимости от
formState
рисовать любую фразу любого цвета, которого хочется. В этом случае вообще не понятно почему цвет текста и текст сообщения были вынесены в состояние. Оставьте это в вёрстке, зачем в состояние то.@prog_way_blog — #review
👍19🔥4🐳3🤔1
Страшные рефы
Есть код:
Как сделал бы я:
Цитата из доки реакта: “Не вызывайте хуки внутри циклов, условных операторов или вложенных функций. Вместо этого всегда используйте хуки только внутри React-функций, до возврата какого-либо значения из них.”. Если это правило не соблюдать, то можно самых странных ошибок огрести.
Подробнее в официальном руководстве
@prog_way_blog — #react #review
Есть код:
const items = [1, 2, 3, 4];
const itemRefs: React.RefObject<HTMLDivElement>[] = items.map(() =>
useRef(null),
);
// и далее в вёрстке
ref={itemRefs[index]}
Как сделал бы я:
// вынести из компонента
const items = [1, 2, 3, 4];
// внутри компонента
const itemRefs = useRef([])
// и внутри вёрстки
// index берется из .map, так как элементы на
// страницу вставляются из списка
ref={element = inputRef.current[index] = element}
Цитата из доки реакта: “Не вызывайте хуки внутри циклов, условных операторов или вложенных функций. Вместо этого всегда используйте хуки только внутри React-функций, до возврата какого-либо значения из них.”. Если это правило не соблюдать, то можно самых странных ошибок огрести.
Подробнее в официальном руководстве
@prog_way_blog — #react #review
🔥11🐳9❤2🤔1
Зачем нужен useCallback
Очень распространенная ошибка, которая говорит о том, что мало кто понимает что такое
Важный вопрос, будет ли ререндерится
И ответ тут очевиден —конечно же да! Не смотря на то, что функцию мы мемоизировали и ссылка на саму функцию у нас не изменилась благодаря
Чтобы получить ожидаемое поведение, необходимо сделать очень важную вещь, а именно — мемоизировать и сам дочерний компонент:
Вот только так и только тогда мы перестанем ререндерить дочерние компоненты, так как пропсы не изменились. При ревью я заметил много случаев, когда useCallback использовать просто не нужно было, но он был.
А ещё много таких было кейсов:
Тут смысл
Пример из доки реакта
@prog_way_blog — #react #review
Очень распространенная ошибка, которая говорит о том, что мало кто понимает что такое
useCallback
и зачем он нужен.Важный вопрос, будет ли ререндерится
Component
при ререндере родителя?const Parent = () => {
const foo = useCallback(() => {
}, [])
return <Component foo={foo} />
}
const Component = (props) => { ... }
И ответ тут очевиден —
useCallback
, мы всё равно перерендерим Component
, поскольку рендерится родитель. Чтобы получить ожидаемое поведение, необходимо сделать очень важную вещь, а именно — мемоизировать и сам дочерний компонент:
const Component = memo((props) => { ... })
Вот только так и только тогда мы перестанем ререндерить дочерние компоненты, так как пропсы не изменились. При ревью я заметил много случаев, когда useCallback использовать просто не нужно было, но он был.
А ещё много таких было кейсов:
const Component = () => {
const foo = useCallback(() => {
}, [])
return <button onClick={() => foo()} />
}
Тут смысл
useCallback
теряется вдвойне, так как в пропсах мы всё равно пересоздаём функцию на каждый рендер вот тут: onClick={() => foo()}
Пример из доки реакта
@prog_way_blog — #react #review
👍20🐳4🔥3🤔1
Кстати, React 19 вышел в публичную бету
Серверные экшены и компоненты, новые хуки, асинхронные обработчики формы, наконец-то переработанные контексты и много чего ещё. Отдельными постами разбираем? 🐳
Пост из блога реакта — публикация от 25 апреля
@prog_way_blog — чат — #news
Серверные экшены и компоненты, новые хуки, асинхронные обработчики формы, наконец-то переработанные контексты и много чего ещё. Отдельными постами разбираем? 🐳
Пост из блога реакта — публикация от 25 апреля
@prog_way_blog — чат — #news
👍41🐳13😁9🔥2
Хочется делать посты чаще
Но это не так просто, потому что каждый свой пост я пишу сам, стараюсь его качественно проработать, идей не так много и всё такое. Может ввести новую рубрику в канал?
Я давно над этим думаю, но ничего невероятного в голову не приходит. Самая классная из моих идей — делать викторины по уже вышедшим постам, буду проверять ваши остаточные знания🤓
И раз уж появился чатик, может, подискутируем на эту тему? Готов рассмотреть любую идею. "Из зала" идею взять всегда приятно, это должно быть максимально интересно для вас, а это и есть моя цель. Если стесняетесь писать в чатик, но идея есть, то напоминаю, что есть личка @denisputnov
Может быть вы чувствуете, что каналу не хватает какого-то контента?
@prog_way_blog — чат — #blog
Но это не так просто, потому что каждый свой пост я пишу сам, стараюсь его качественно проработать, идей не так много и всё такое. Может ввести новую рубрику в канал?
Я давно над этим думаю, но ничего невероятного в голову не приходит. Самая классная из моих идей — делать викторины по уже вышедшим постам, буду проверять ваши остаточные знания
И раз уж появился чатик, может, подискутируем на эту тему? Готов рассмотреть любую идею. "Из зала" идею взять всегда приятно, это должно быть максимально интересно для вас, а это и есть моя цель. Если стесняетесь писать в чатик, но идея есть, то напоминаю, что есть личка @denisputnov
Может быть вы чувствуете, что каналу не хватает какого-то контента?
@prog_way_blog — чат — #blog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥21👍6🐳1🍌1
Лучшие практики типизации
В рамках ведения проектов и код-ревью я частенько натыкаюсь на странности написания TypeScript кода. В этом посте я постарался собрать самые частые ошибки, на которые точно стоит обратить внимание.
1. Лишний контекст
2
Сила
Проблема использования
3. Злоупотребление
4. Использование
5. Злоупотребление оператором
6. Отдельным и крайне важным для меня пунктом выделю оформление
Обратите внимание на то, что
Это самые частые ошибки, что мне приходилось комментировать. Все эти правила можно прочитать в официальном TypeScript Handbook и Google JavaScript Style Guide. Это не мои выдумки — это правила, закреплённые индустрией.
Спасибо за прочтение, это важно для меня ❤️
@prog_way_blog — чат — #web #theory #typescript
В рамках ведения проектов и код-ревью я частенько натыкаюсь на странности написания TypeScript кода. В этом посте я постарался собрать самые частые ошибки, на которые точно стоит обратить внимание.
1. Лишний контекст
// плохо
type Person = {
personName: string;
personAge: string;
}
// замечательно
type Person = {
name: string;
age: string;
}
2
. enum
везде. Даже там, где не нужно. Сила
enum
заключается в том, что помимо перечисления внутри контекста, enum
можно использовать в качестве типа. Если вы не планируете использовать перечисления как тип, а лишь маппите что-либо в рамках одной сущности, то используйте константные объекты:const Status = {
Success: 'success',
Fail: 'fail'
} as const;
Проблема использования
enum
гораздо глубже, чем может показаться на первый взгляд. Думаю, что ей можно посвятить отдельный пост.3. Злоупотребление
any
. Я не противник использования any
в случаях, где это действительно необходимо, но многие, даже высокого грейда разработчики, не понимают зачем конкретно он нужен. Прежде, чем воткнуть any
, пожалуйста, попробуйте использовать unknown
. Это сделает ваш код гораздо безопаснее.4. Использование
Definite Assertion
оператора. Это когда вы утверждаете оператором восклицательного знака !
, что значение точно есть, хотя оно может быть и undefined
:// так делать не нужно, лучше добавить дополнительное условие
const foo = (arg?: string) => parseInt(arg!)
5. Злоупотребление оператором
as
. Ровно та же проблема, что с any
. Самый частый пример, что мне доводилось видеть:type Person = {
name: string
}
// плохо
const person = {
name: "Denis"
} as Person
// замечательно
const person: Person = {
name: "Denis"
}
6. Отдельным и крайне важным для меня пунктом выделю оформление
enum
. Согласно всем стайл-гайдам мира, enum
— сущность, группа, в единственном числе, оформленная определенным образом.// плохо
enum OPERATION_STATUS {}
enum STATUSES {}
enum STATUS {}
enum HTTPStatus {}
// замечательно
enum OperationStatus {}
enum Status {}
enum HttpStatus {}
Обратите внимание на то, что
Http
я написал не капсом. Аббревиатуры в названии любых переменных оформляются именно так, а не как HTTP
. Также название enum
-a пишется в PascalCase
. Таким же образом оформляются и ключи enum
-a:// плохо
enum Status {
SUCCESS,
FAIL
}
// замечательно
enum Status {
Success,
Fail
}
Это самые частые ошибки, что мне приходилось комментировать. Все эти правила можно прочитать в официальном TypeScript Handbook и Google JavaScript Style Guide. Это не мои выдумки — это правила, закреплённые индустрией.
Спасибо за прочтение, это важно для меня ❤️
@prog_way_blog — чат — #web #theory #typescript
🔥34👍15❤6🐳2
Flash of unstyled content
Эта проблема — это тот случай, когда при загрузке страницы на долю секунды проскакивает нестилизованный контент. Как будто бы с сайта удалили все стили. И происходит это из-за того, что HTML уже построен, а стили — нет, или просто произошла ошибка при их загрузке.
Браузер уже имеет готовое DOM дерево, но всё ещё ожидает генерации CSS Object Model (CSSOM). FOUC появляется как раз до тех пор, пока не построится CSSOM. После его генерации создается дерево рендеринга и страница перерисовывается стилизованной. Выглядит это, зачастую, как вспышка белого на экране, особенно если сайт имеет какой-то специфичный фон. Отсюда и такое специфичное название.
Избежать подобной проблемы можно несколькими способами:
— Внести критический набор стилей в сам HTML, то есть описать основные стили в теге
— Использовать проактивную загрузку стилей, то есть использовать
Тут мы помечаем файл
Почему-же это важно? Всё дело в том, что наличие FOUC сильно портит пользовательский опыт, а в ночное время суток и вовсе бьёт по глазам, что вызывает отторжение у пользователей, особенно при использовании темной темы на сайте. Стилизация, в целом, играет важную роль в восприятии. Качественная работа со стилями может повысить продажи.
Спасибо за прочтение, это важно для меня ❤️
@prog_way_blog — чат — #web #theory
Эта проблема — это тот случай, когда при загрузке страницы на долю секунды проскакивает нестилизованный контент. Как будто бы с сайта удалили все стили. И происходит это из-за того, что HTML уже построен, а стили — нет, или просто произошла ошибка при их загрузке.
Браузер уже имеет готовое DOM дерево, но всё ещё ожидает генерации CSS Object Model (CSSOM). FOUC появляется как раз до тех пор, пока не построится CSSOM. После его генерации создается дерево рендеринга и страница перерисовывается стилизованной. Выглядит это, зачастую, как вспышка белого на экране, особенно если сайт имеет какой-то специфичный фон. Отсюда и такое специфичное название.
Избежать подобной проблемы можно несколькими способами:
— Внести критический набор стилей в сам HTML, то есть описать основные стили в теге
<style>
в шапке index.html
файла. Таким образом, мы гарантируем создание CSSOM ещё до отрисовки контента на странице, что решает проблему.— Использовать проактивную загрузку стилей, то есть использовать
preload
для тега link
, выглядеть это может примерно вот так:<link rel="preload" href="style.css" as="style" />
<link rel="stylesheet" href="style.css" />
Тут мы помечаем файл
style.css
для предварительной загрузки, что также решает проблему.Почему-же это важно? Всё дело в том, что наличие FOUC сильно портит пользовательский опыт, а в ночное время суток и вовсе бьёт по глазам, что вызывает отторжение у пользователей, особенно при использовании темной темы на сайте. Стилизация, в целом, играет важную роль в восприятии. Качественная работа со стилями может повысить продажи.
Спасибо за прочтение, это важно для меня ❤️
@prog_way_blog — чат — #web #theory
🔥39👍7🐳4❤2
Пример тестового задания из Авито
Интересностей пост, чтобы понимать, к чему стоит стремиться новичку фронтендеру. В этом посте кратко разберу тестовое задание на стажировку из Авито 2024 года.
Вот основные требования, которые я вычленил из описания задания:
— умение использовать React, его хуки в связке с TypeScript
— умение создавать свои собственные хуки
— умение реализовать переход на другую страницу в рамках приложения
— умение работать с API и Swagger, может пригодиться axios
— умение работать с переменными окружения
— сохранение и восстановление состояния из url query параметров
— базовое понимание и настройка Webpack
— базовое понимание Node JS
— базовое понимание docker
— базовое понимание самых простых UI unit тестов
По вёрстке, необходимо уметь отображать:
— Выпадающие списки
— Изображения
— Списки компонентов
Также необходимо понимать что такое адаптивная вёрстка и уметь верстать не только для своего ПК, но и для любого другого устройства, в том числе для мобильных телефонов, планшетов и прочего.
Что важно, но в тестовом об этом не сказано:
— базовое понимание того что такое архитектура, умение строить более-менее чистую файловую структуру проекта
— грамотное использование git в процессе разработки, хотя бы не одним коммитом проект нужно заливать
— понимание того, как работают стили, как сделать более-менее симпатичный и удобный интерфейс
Напугало ли вас это? Очень надеюсь, что нет. Если подумать, то это тестовое задание очень даже не сложное. Для начинающего разработчика, который пишет 3-4 проект в жизни, очень даже реально реализовать такое за пару дней в спокойном и размеренном темпе.
Кажется, что знать нужно очень много, но очень многое из тем, что я описал выше, на достаточном для выполнения тестового уровне, изучается максимум минут за 30, а если это не первый проект в вашей жизни, то с 80% требований вы уже точно встречались и уже имели бы нужный опыт в разработке.
Полный текст тестового задания
Спасибо за прочтение, это важно для меня ❤️
@prog_way_blog — чат — #web
Интересностей пост, чтобы понимать, к чему стоит стремиться новичку фронтендеру. В этом посте кратко разберу тестовое задание на стажировку из Авито 2024 года.
Вот основные требования, которые я вычленил из описания задания:
— умение использовать React, его хуки в связке с TypeScript
— умение создавать свои собственные хуки
— умение реализовать переход на другую страницу в рамках приложения
— умение работать с API и Swagger, может пригодиться axios
— умение работать с переменными окружения
— сохранение и восстановление состояния из url query параметров
— базовое понимание и настройка Webpack
— базовое понимание Node JS
— базовое понимание docker
— базовое понимание самых простых UI unit тестов
По вёрстке, необходимо уметь отображать:
— Выпадающие списки
— Изображения
— Списки компонентов
Также необходимо понимать что такое адаптивная вёрстка и уметь верстать не только для своего ПК, но и для любого другого устройства, в том числе для мобильных телефонов, планшетов и прочего.
Что важно, но в тестовом об этом не сказано:
— базовое понимание того что такое архитектура, умение строить более-менее чистую файловую структуру проекта
— грамотное использование git в процессе разработки, хотя бы не одним коммитом проект нужно заливать
— понимание того, как работают стили, как сделать более-менее симпатичный и удобный интерфейс
Напугало ли вас это? Очень надеюсь, что нет. Если подумать, то это тестовое задание очень даже не сложное. Для начинающего разработчика, который пишет 3-4 проект в жизни, очень даже реально реализовать такое за пару дней в спокойном и размеренном темпе.
Кажется, что знать нужно очень много, но очень многое из тем, что я описал выше, на достаточном для выполнения тестового уровне, изучается максимум минут за 30, а если это не первый проект в вашей жизни, то с 80% требований вы уже точно встречались и уже имели бы нужный опыт в разработке.
Полный текст тестового задания
Спасибо за прочтение, это важно для меня ❤️
@prog_way_blog — чат — #web
👍31🐳6❤3🔥2
Ну щас я проверю как вы мои посты читаете🤭
@prog_way_blog — чат — #quiz
console.log(name);
console.log(age);
var name = "progway";
let age = 4;
@prog_way_blog — чат — #quiz
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11🐳5🗿2👍1🍌1