Илья Юркин | Easy JS
1.21K subscribers
72 photos
70 links
Полезные советы от senior разработчика.

Менторство: https://bit.ly/mentor-yurkin

По всем вопросам: @i_urKing
Download Telegram
Борьба с лишними ререндерами

Лайфхак для тех, кто хочет повысить производительность форм и полей ввода, в частности.
Вы без проблем можете заменить хранение value в useState на useRef, если в onChange колбэках нет сложной логики и другие компоненты или хуки не зависят от value. Читаемость от этого почти не пострадает, а вот количество ререндеров сильно уменьшится, что хорошо скажется на производительности, особенно, в больших компонентах.

Этот подход можно масштабировать, но чтобы не снижать читаемость, рекомендую обзавестись кастомными хуками или использовать менеджер форм типа React Hook Form. У них хорошая дока, а на базовой странице есть наглядный пример, который показывает разницу в количестве ререндеров относительно менеджеров форм, которые используют стейты.

#react
👍9🔥3🤯2🤩1🍾1
Внимание к названиям сущностей

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

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

Рассмотрим пример. Допустим, есть объект книги (Book), в котором содержится поле read. Сможете ли вы, глядя на название поля, определить его тип? Это булево поле? Дата? А если дата, то в каком формате? TypeScript, отчасти, сглаживает плохой нейминг. Можно создать интерфейс IBook и в нем задать тип для свойства read. Но, глядя на код, все еще проблематично определить тип. Нужно навести мышкой на переменную, а в некоторых случаях, еще и провалиться в тип, для более подробного изучения, да и не все проекты используют TS.

Даже с использованием TS лучше давать имена переменным более звучно. Для булевых переменных можно добавлять вопросительные приставки: is, has и т.д.. Переменная isRead однозначно дает понять, что в ней содержится булевое значение. Если же в переменной содержится дата, то можно добавить суффикс at, например, readAt. Или уточнить тип даты более конкретно: readDateISO, readDateUNIX, readDateObject.

Функции заслуживают отдельного внимания. Иногда встречаются функции типа booksRead. Что делает и возвращает эта функция? Ищет прочитанные книги? Помечает их прочитанными? Пока не провалишься в функцию - не определишь. Самый простой совет - начинайте названия функции с глагола и, по необходимости, добавляйте контекст. Получить список прочитанных книг - getReadBooks, найти книгу по id - findBookById, обновить книгу - updateBook, ручка для обработки колбэка - handleBookRead

#js
👍18🔥51
Дефолтные значения при деструктуризации

Многие знают как JS сравнивает не примитивные значения. Поэтому, при необходимости, мемоизируют или выносят за рендер такие переменные в рекакте. Но при деструктуризации пропсов с дефолтными значениями, как будто появляется слепая зона 😅.

Допустим, у MyComponent есть необязательный проп users и для удобства разработчик выставил пустой массив как дефолтное значение (скрин 1). Все было хорошо до того момента, пока не добавили дополнительную логику: isLoading проп, стейт и пару хуков (скрин 2). Теперь при каждом изменении state или isLoading, если проп users не передан, то реакт будет создавать новый массив каждый ререндер, пока не получит существующее значение. Это все равно что писать const users = []. Из-за такого опущения часто случаются лишние ререндеры или даже сайдэффекты. Кейс хоть и хитрый, но есть довольно много путей решения:

1. Если users приходят асинхронно, то можно выставить ему дефолтное значение на уровне хранилища и убрать из компонента.
2. Вынести пустой массив в константу за пределы компонента
const DEFAULT_USERS = []
const MyComponent = props => {
const { users = DEFAULT_USERS } = props
...
3. Добавить проверку на уровне родителя, чтобы не рендерить MyComponent, если в users пусто.
4. Обрабатывать undefined значение в компоненте. Не очень удобно когда от пропа много зависимостей.

Следите за дефолтными значениями при деструктуризации.

#react
👍114🔥4
Лайфхак для тех, кто использует IDE от jetbrains и давно хотел научится пользоваться шорткатами: установите Key Promoter X плагин. Он показывает подсказку с комбинацией клавиш, всякий раз, когда вы делаете действие мышью, для которого существует шорткат.

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

Самое сложное – начать применять и запоминать комбинации, т.к. изначально скорость работы с мышкой проще и быстрее, но, по мере привыкания к шорткатам, скорость работы с ними обгоняет мышку.

P.S. На скрине моя стата за последнее время. Я долгое время использовал SourceTree для работы с гитом. Поэтому шорткаты, что связаны с гитом, я все еще вспоминаю постфактум 🤷‍♂️

P.P.S. Если у кого-то есть аналогичный плагин для VS code – поделитесь в комментах.

#plugins
👍16🔥1🤩1
Задача: Восхождение по лестнице

Задача про лестницу, которая может помочь начать восхождение по карьерной лестнице 🤔

Условие: Вы поднимаетесь по лестнице. Требуется n шагов, чтобы добраться до вершины.

Каждый раз вы можете подняться на 1 или 2 ступеньки. Сколько существует различных способов, чтобы подняться на вершину?

Пример 1:
Ввод: n = 2
Вывод: 2
Объяснение: Здесь 2 способа подняться на вершину.
1. 1 шаг + 1 шаг
2. 2 шага

Пример 2:
Ввод: n = 3
Вывод: 3
Объяснение: Здесь 3 способа подняться на вершину.
1. 1 шаг + 1 шаг + 1 шаг
2. 2 шага + 1 шаг
3. 1 шаг + 2 шага

Пример 3:
Ввод: n = 4
Вывод: 5
Объяснение: Здесь 5 способов подняться на вершину.
1. 1 шаг + 1 шаг + 1 шаг + 1 шаг
2. 2 шага + 1 шаг + 1 шаг
3. 1 шаг + 2 шага + 1 шаг
4. 1 шаг + 1 шаг + 2 шага
5. 2 шага + 2 шага

Пишите свои версии в комментариях.

Ответ с объяснением 👈

#algorithms
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥2🤔1
Борьба с лишними ререндерами #2

Недавно
разбирал проект, в котором разработчик хотел уменьшить бойлерплейт, а в итоге, выстрелили себе в ногу. Он прокидывал в useSelector именную функцию, в которой вытягивал и преобразовывал нужные значения из redux хранилища, а потом делал деструктуртуризацию в компоненте. Вероятно, это была попытка сделать аналог mapStateToProps чтобы не плодить селекторы. К сожалению, это так не работает.

Одно из отличий useSelector и mapStateToProps гласит: когда диспатчится любой экшен, useSelector делает ссылочное сравнение предыдущего значения и нового. Если они отличаются, компонент будет принудительно перерендерен. То есть, если внутри useSelector создавать новый объект, то компонент будет ререндериться на каждое изменение стора. Кстати, это касается и дефолтных значений (подробнее в этом посте).

Какие выводы?
1. Избегать в useSelector преобразований объектов
2. Если нужно дефолтное значение - объявить его в инициализаторе стора
3. Если нужен производный объект из нескольких значений стора - создать на каждое значение отдельный useSelector и, уже внутри компонента, сделать нужное преобразование. Если подобные манипуляции нужны часто, используйте MobX reselect

#react
👍14🔥2🤔21
Сжатие изображений

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

Обычно процесс добавления изображения выглядит так: экспорт из фигмы -> перенос в public папку. Рекомендую добавить третий шаг: перед добавлением в проект прогнать изображение через tinypng. Естественно, никто не запрещает обновить уже существующие картинки в проекте 😃. Вас приятно удивит, что некоторые изображения уменьшатся на 80-90% без потери качества, что положительно скажется на скорости загрузки, особенно, на лендингах.

Кстати, инструмент пригодится и бэкендерам. У tinypng есть API, который позволяет сжимать картинки по запросу. Подойдет, например, для сжатия картинок при загрузке через админку.

P.S. На картинке пример сжатия скриншота из WebStorm. А это даже не полный экран!
👍15🔥6🤩1
Грокаем алгоритмы

Эту книгу часто рекомендуют начинающим программистам, но я также хочу порекомендовать ее и миддлам+, которые уже уверенно шарят в алгоритмах и хотят прокачать свой технический английский.

Книга написана достаточно простым языком, да еще и с картинками. Если вы читаете англоязычные ответы на stackoverflow, то и книга вам будет по силам.

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

P.S. Книгу на обоих языках скинул в комменты.

#algorithms
👍156🔥3
Задача: Лучшее время для покупки и продажи акций

Дан массив prices, где prices[i] — цена акции на i-й день.

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

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

Пример 1:
Ввод: prices = [7,1,5,3,6,4]
Вывод: 5
Объяснение: Обратите внимание, что покупка во 2й день и продажа в 1й день не возможны, потому что вы должны купить перед продажей.

Пример 2:
Ввод: prices = [7,6,4,3,1]
Вывод: 0

Пример 3:
Ввод: prices = [7,3,5,1,10,4]
Вывод: 9

Пишите свои версии в комментариях.

Ответ с объяснением 👈

#algorithms
👍9🤔6🔥2
Работа с SVG: шрифт, компоненты или файлы?

Упаковка SVG в шрифт будет разумным выбором, если у вас огромное количество иконок. Это позволит использовать те же CSS подходы, что и при работе с обычным шрифтом. Использование SVG шрифта может помочь уменьшить размер приложения, так как понадобится подключить только один файл, который может еще и кешироваться в дальнейшем.

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

И, наконец, статические SVG файлы. Небольшое количество SVG картинок, которые не требуют никаких манипуляций в коде, можно разместить в статических файлах. Такие картинки будут кэшироваться, но манупуляция будет проблематичной.

Когда какой подход использовать? Статику я бы использовал на лендингах, т. к. там важно время загрузки и, как правило, картинки в малом количестве, что делает использование шрифта не очень выгодным. Шрифты имеет смысл генерировать для больших корпоративных паков иконок и закидывать на CDN, чтобы системы и микросервисы не грузили одни и те же файлы иконок, а использовали закашированный шрифт. Ну, и во всех остальных случаях я бы выбрал SVG, как react-компонент, в идеале, в отдельном пакете. Если закрыть глаза на скорость загрузки и билда, то SVG как компоненты, безусловно лидируют: вы, как разработчик, полностью владеете кодом и видите историю всех изменений в гите, а у конечных пользователей не прыгает страница (в случае долгой загрузки статики) и не появляются квадратики (пока идет загрузка шрифта)

#react #js
👍9🔥31🤔1
Задача: Идентичность деревьев

Даны корни двух бинарных деревьев P и Q, напишите функцию, чтобы проверить, являются ли деревья одинаковыми.

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

P.S. В телеге проблематично оформить наглядный пример деревьев с картинками. Кому нужны картинки – переходите к статье с ответом. Раздел до "Решения" не содержит спойлеров.

Пример 1:
Ввод: p = [1,2,3], q = [1,2,3]
Вывод: true

Пример 2:
Ввод: p = [1,2], q = [1,null,2]
Вывод: false

Пример 3:
Ввод: p = [1,2,1], q = [1,1,2]
Вывод: false

Пишите свои версии в комментариях.

Ответ с объяснением 👈

#algorithms
👍7🔥2🤔2
Избегание мыслительной нагрузки

Частно встречаю "короткие" и "простые" решения под задачками с алгоритмами. Типа использование split, reverse, join для переворота строки или сравнение объектов через JSON.strigify/parse.

Знание подобных практик, безусловно, обязательно, вот только мыслить алгоритмически они не особо помогают. При решении алгоритмов нужно прокачивать скилл понимая и решения алгоритмов, а не пытаться вспомнить все методы языка. В идеале, обходиться минимальным набором: объявление переменных, условия и циклы. А все вот эти map, filter, split и т.д. оставить для решения рутинных прикладных задач на реальных проектах.

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

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

P.S. вот тут оставлял книгу по алгоритмам, а по тэгу #algorithms можно найти решение задач с leetcode с пояснениями
👍13🔥21
Context API vs Redux

На первый взгляд Context API может показаться достойной заменой redux: механизм использования очень похожий, не нужно тянуть дополнительные зависимости, все есть из коробки. Однако у Context API, есть проблемы производительности. Компоненты, которые используют контекст, ререндерятся при любом изменении состояния, а не только тех полей, которые используют эти компоненты.

На скрине упрощенный и абстрактный пример. Допустим, объект хранилища состоит всего из двух полей: user и theme. Если нажать на Button и изменить тему, то Header тоже перерисуется, хоть user и не изменился. И тут дело не в том, что value в примере не мемоизирован, а в том, как работает контекст. Нужно пересоздавать главный объект стора при любом изменении, иначе, слушатели просто не среагируют на изменения.

Хотя с использованием useReducer можно построить структуру похожую на ту, что мы привыкли видеть в redux, я бы не рассматривал Context API как полноценную замену redux. А вот для управления состоянием в отдельных небольших модулях вполне, например, в компонентах UI кита.

P.S. вот хорошая статья для тех, кто хочет углубится в тему: https://blog.thoughtspile.tech/2021/10/04/react-context-dangers/

#react
👍10🔥32
Во время подготовки поста вспомнил другие интересные менеджеры состояний. О некоторых слышал/использовал раньше, но почти все мои текущие проекты используют redux, и протестить другие менеджеры, хотя бы на средних проектах, пока нет возможности 🥲

Стало интересно, насколько популярен redux сегодня?
👍5
Какие менеджеры состояний вы используете в своих React проектах?
Anonymous Poll
74%
Redux/Redux toolkit
1%
Rematch
2%
Recoil
13%
MobX
9%
Zustand
2%
Jotai
18%
React Query
21%
Context API
12%
Другой менеджер
Хочу порекомендовать вам канал моего талантливого товарища, ios разработчика. Если хотите узнавать о последних технологиях и инструментах, которые используются в ios разработке, то залетайте.

https://t.iss.one/ios_prog
👍32🔥1
Нейросети. Первая часть.

Уже давно собираюсь рассказать свою точку зрения о нейросетях, но все время откладываю. Анонс GPT-4 и релиз MidJourney v5 дали мне пинок силы. Попытался рассказать свой опыт с разных сторон, но в итоге, получилось много текста, поэтому решил разбить пост на несколько частей. Начну с самого популярного – программирования.

Одни утверждают, что нейросети уже заменяют программистов, другие – что они все еще бесполезные. Я считаю, что реальное положение дел где-то посередине.

Думаю те, кто просил ChatGPT сделать что-то прикладное, а не "хеллоу ворлд", сталкивались с тем, что результаты далеко не всегда корректны и полезны, даже после уточнений. Вот из-за подобных промахов я отношусь к нейросетям, как к карманным джунам 😂
Да, код написать они могут, но нужен контроль и доработка от кого-то более опытного. Следовательно, запросы к ним должны быть соответсвующие. Если попросить создать код для целой бизнес задачи или раздела, то проблем будет больше, чем пользы. А вот если декомпозировать задачу на маленькие кусочки и попросить помощи с этими маленькими частями, то можно поймать профит.
Лично для меня подобный вариант использования все еще не несет существенной пользы, т.к. большинство рутины автоматизируют сниппеты и генераторы, а то, что они не покрывают, я могу описывать дольше, чем сделать ручками. Буду экспериментировать с 4 версией и поделюсь результатами позже.

Единственное, что я пока иногда делаю со своим кодом это отправляю его ChatGPT и прошу улучшить или отрефакторить, а потом читаю советы. Очень часто выдает спорные суждения, но бывают и реально годные. Например, когда что-то упустил в силу человеческого фактора.

P.S. Да, я знаю, что тот же ChatGPT может написать работающий код приложения, но кто будет поддерживать проекты, которые сгенерировали нейронки? 🤔
Please open Telegram to view this post
VIEW IN TELEGRAM
👍146🤔1💩1
CodeGPT

Кстати, буду стараться показывать лайфхаки и инструменты, которые сам использую. Бонусом к первой части я бы посоветовал пощупать плагин CodeGPT: JetBrains версия, VS Code версия. Позволяет легко и удобно скармливать ваш код ChatGPT.

Из коробки можно попросить:
- Объяснить код
- Отрефакторить
- Найти баги
- Написать тесты
- Оптимизировать

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

P.S. Для использования нужно быть зарегистрированным в ChatGPT.

#plugins
👍12🔥42