Как стать автором
Обновить
36
0

Frontend developer (React, MobX)

Отправить сообщение

Для добавления объекту новой функциональности есть 3 подхода - смешивание с другим объектом, обертка другим объектом, замена объектов/функций в полях-ссылках объекта на другие объекты/функции.

Вариации 3-го подхода:
Можно вынести метод в функцию вне класса и вызывать ее в соответствующем методе жизненного цикла в нужных компонентах.

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

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

Реализацию такого подхода я описывал в https://habr.com/ru/articles/545064

<skz>Вот же этот Ден Абрамов, стервец, дурачит газилионы и газилиарды разработчиков!</skz>

Пишу на реакте с 2015-го. И что-то не ощущаю профита в разработке от стольких лет его эволюции. Скорее наоборот, разработка на нем стала сложнее и медленнее(

под fsd вы имеете ввиду использования feature-list вместо layer-list структуры топлевел директорий

Под fsd я имею ввиду то же, что и автор статьи - https://feature-sliced.design/ru/
Вы верно подметили про layer-list - что неудобно распределять фичу по топлевел директориям. FSD как раз грешит этим.

Про MV* не совсем понял. Это же паттерны презентации, а не архитектура ...

Я тоже не совсем понял, что именно вы имеете ввиду под архитектурой?) Ок, именно они - не архитектура, а паттерны, используемые для разбиения приложения на слои в многослойной архитектуре.
Но я согласен, что эти слои должны находиться рядом для конкретного виджета/страницы.

Люди слишком много думают, а на деле фсд очень даже простой)

Судя по множеству вопросов и разногласий даже среди senior разрабов в том, что и где должно лежать, фсд на самом деле довольно сложный)

Даже выше в комментах было:

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

Всё это разделение на множество слоев ради переиспользования без кросс импортов скорее приводит не к упрощению, а к усложнению. Плюс функционал, связанный с одной бизнес сущностью, становиться разбросан по нескольким слоям проекта. Думаю, в большинстве проектов было бы эффективней не делить на слои widgets, features, entities, а объединить эти 3 слоя в один слой и разрешить в нем кросс импорты между слайсами.

Тоже добавлю про fsd. Решили его попробовать на текущем среднем проекте - несколько десятков тысяч строк кода.

Плюсы:

  • Много документации по подходу.

  • Хорошая идея с разделением на слайсы, сегменты.

  • Знакомишься со сторонними идеями по улучшению файловой структуры проекта.

Минусы:

  • В ходе работы возникает путаница, когда разговор заходит о слоях. В архитектурах MV*, Flux и т.д. слоями называется другое.

  • При разработке возникает много непонятных моментов - какие слои нужны именно в твоем случае (а при избегания кросс-доменности складывается впечатление, что понадобятся все), к какому слою относится тот или иной функционал (у всех вызывает сложность, когда надо определиться, данный модуль это feature или entity? Также возникают сложности с определением, куда поместить такой функционал, как локализация, темизация, переиспользуемые пагинация/сортировка/фильтрация). Все в какой-то степени по-разному понимают FSD, поэтому в команде скорее всего будут частые обсуждение, что и где должно лежать.

  • Логика страницы вместо того, чтобы находиться рядом в соседних файлах/папках, постоянно размазывается по 3-4 папкам - pages, widgets, features, entities. Это повышает когнитивную нагрузку. Часто приходиться переключаться между далеко расположенными друг от друга папками. На мой взгляд, структурировать проект, беря декомпозицию компонентов за значительную часть основы - это не удачный подход.

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

  • Сложно контролировать на code review, т.к. сходу часто не понятно, в какой слой правильней поместить новый модуль.

В следующем проекте вместо слоев FSD, я подумываю использовать примерно следующие:

  1. app - по аналогии с FSD

  2. pages - конкретные страницы и всё (включая конкретные api), относящееся только к конкретной страницы. (вместо постоянного разделения на pages, widgets, features, entities по FSD)

  3. reusable-in-pages - переиспользуемый функционал для нескольких страниц. (вместо widgets, features, entities по FSD)

  4. components - переиспользуемые визуальные компоненты, а также react хуки/улилиты и т.д., относящиеся к этим компонентам.


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

    Хотя возможно 4-ый и 5-ый слои лучше объединить в один, т.к. некоторый функционал (например, toasts) связан с компонентами. А возможно shared стоит использовать как в FSD. Т.е. 4-6 слои из моего комментария сделать одним слоем.

  5. shared-business - переиспользуемый функционал, не относящаяся к конкретным страницам или к какой-либо группе страниц, но привязанная к работе, процессам именно этого приложения. (вместо shared/libs по FSD)

  6. shared-not-business - всё прочее переиспользуемое, не привязанное к приложению, и которое в теории может быть переиспользовано в любом другом проекте. В основном это типы, утилиты, некоторые react-hook-и. (по аналогии с FSD, но без shared/ui и без shared/libs)

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

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

Про то, что хуки это исключительно стратегия не соглашусь

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

Единственным способом переиспользования классовых методов жизненного цикла - является как раз написание HOC’ов.

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

HOC - это аналог паттерна "декоратор" для функциональных компонентов.

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

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

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

Касательно хуков. Группа хуков, вызов которых прописан в конкретном функциональном компоненте - это фиксированный список "стратегий". В геймдеве давно есть похожий подход, но применяемый к объектам/классам. Но там используется не фиксированный список, а динамический. Плюс более грамотное разделение ответственности. В реакте же компонент является и контейнером для стратегий (хуков), содержит в себе разметку, а также позволяет писать логику в самих компонентах. Такое объединение функционала является недостатком как функциональных, так и в классовых компонентах. Это нарушение принципа SRP, приводящее к уменьшение гибкости компонента и менее качественному коду пользователей react-а.

Недавно наткнулся на видео на ту же тему, что и ваша статья
https://www.youtube.com/watch?v=c3JGBdxfYcU
У меня вопросы:

  1. С каких пор во фронтенде архитектурой стали называть организацию структуры папок в проекте?

  2. "Components, Store, Containers", "Feature Oriented" - откуда взяты такие названия для подходов?

В Redux используется паттерн издатель-подписчик. В вашей статье описан тоже он.

Паттерн наблюдатель немного другой. По ссылке описана разница между ними:
https://medium.com/clean-code-channel/observer-vs-pub-sub-pattern-4fc1da35d11

useEffect(() => {
  (async () => {
    const {data} = await axios.get('api/posts')
    setPosts(data)
  })()
}, [])

Я бы предпочел избавиться от такого количества скобок и писать например так:

useMountEffectAsync(async () => {
  const {data} = await axios.get('api/posts')
  setPosts(data)
})

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

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

Думаю, BuccapuoH, как и я, хотел узнать, что у вас за проект такой, в котором понадобилось столько раз использовать requestAnimationFrame и process.nextTick) И была ли в этом необходимость или же это просто преждевременная оптимизация.

Стандартные подходы Vue, где во Vuex экшенах делаются запросы и кладутся в стор и т.п не расширяемые

Мне тоже всегда виделось, что это плохо масштабируется. Поэтому вынес из стора обращения к сервисам в отдельный слой, похожий на описанный у вас презентер. Правда на React пишу, но они с Vue довольно похожи.

Принципы SOLID конечно помогают, но одних их довольно маловато. Существует довольно много паттернов, подходов, позволяющих улучшить переиспользование кода. Я, кстати, писал статью о тех, с которыми знаком: https://habr.com/ru/post/545368/

Видимо я ошибался. Теперь начинаю видеть преимущества подхода, особенно в плане оптимизации. А недостаток в виде раздувания FormItem обходится с помощью вынесения логики из него в хуки, сторы. Спасибо, что открыли мне глаза!)

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

С формиком и react-hook-form не работал. И на глаза практически не попадался подход с вынесением общих пропсов в функции. А вот клонирование часто встречалось.

Не обратил внимание при просмотре статьи на задачу вокруг интеграции общей обертки.

например как в вашем случае лучше решить кейс с выводом сообщения о текущем статусе валидации для поля формы

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

У вас типичный и сомнительный вариант с использованием обертки и клонирования элемента ради вынесения общих props-ов. Не понимаю, почему всех тянет так делать. Задача ведь состоит в том, чтобы избавиться от дублирования пропсов. А значит надо для начала посмотреть, что можно сделать с пропсами, а не с элементом.

Вот более удобный вариант, который к сожалению мало кто видит:

<Input {...commonInputProps(name)} />

В функции commonInputProps уже нужная логика с сохранением/мемоизацией куда нужно по имени поля и возврат объекта с данными именно для этого поля.

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

Масштабно подобное не применяю, т.к. для этого потребуется самому писать и поддерживать обертку над react-ом, что затратно и выглядит не привычно для других разработчиков.
Применял бы, если бы писал библиотеку компонентов, используемую другими командами, т.к. react-way не очень хорош для этого.

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

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

Английский от B1. Вся документация и задачи на бордах строго на английском.

Только для чтения нужен от B1 или нет? Больше 10 лет назад работал в компании, где документация и задачи были на английском. Плюс ежедневные отчеты, комментарии в коде, текст коммитов нужно было писать на английском. У половины команды английский был A1-A2, но это не особо мешало работе. Конечно, работали не не без программ-переводчиков для непонятных частей текста.

1
23 ...

Информация

В рейтинге
Не участвует
Откуда
Омск, Омская обл., Россия
Зарегистрирован
Активность