Pull to refresh

Comments 57

Написание собственных библиотек, вместо существующих с открытым исходным кодом

Хмм и откуда по вашему взялись все эти библиотеки (тут список из вашего package.json), как и сам React?

вместо существующих

Речь скорее про велосипеды.

Angular — велосипед
Vue — велосипед рожденный под впечатлением от Angular
React — велосипед, в его JSX это «огрызок» от E4X


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

Не все «велосипед», что делается с нуля. Сейчас на рынке не найдется места второму React или Angular, которые не предложат чего-то большего (что делали они когда-то). Это и будет изобретением велосипеда. Цена должна быть адекватна профиту.

Нет «всё», вы просто не понимаете простую истину, если бы в своё время, эти инструменты не были вынесены на суд общественности как opensource, они никогда не смогли превратиться из обычного местечкового велосипеда в то чем они стали.

эти инструменты не были вынесены на суд общественности как opensource, они никогда не смогли превратиться

«Суд общественности» рукоплескал еще одним яйцам в профиль или у нее были какие-то киллер-фичи, которые общественности полюбились?

как opensource

Вопросы лицензии — это вообще ортогональное понятие. Есть море проприетарных решений, которые пользуются популярностью.
«Суд общественности» рукоплескал еще одним яйцам в профиль или у нее были какие-то киллер-фичи, которые общественности полюбились?

По началу, сообщество очень и очень холодно приняло тот же React или Angular 2. А если б в Vue был менее сырым и за ним стоял бы не никому неизвестный «чувак», а какая-нибудь крупная компания, то кто знает, какая бы расстановка сил была бы сейчас.

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

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


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

По всей видимости, речь идет о том, что если какая-то библиотека устраивает, но не нужно писать свою — достаточно использовать существующую. А вот если нет, то либо форк, либо свое.
Пожалуйста, не пытайтесь запихнуть на одну страницу больше одного экземпляра React приложения. [...] оптимизация такого подхода и согласование всех частей приложения, в этом случае начинает занимать больше половины всего рабочего времени

А что именно тут надо оптимизировать и согласовывать?


В моём представлении, несколько экземпляров React на странице возникают в ситуации, когда нужно разместить React-компонент на странице, построенной по другой технологии (angular, vue или даже jquery). Разумеется, в таком случае согласование компонентов отдаётся на откуп этой самой другой технологии — и не может быть проще чем согласование двух обычных компонентов на этой технологии. Но и сложнее оно не становится просто из-за того, что React-компонентов на странице стало аж два!

Речь о том, что в подавляющем большинстве случаев две React точки входа в приложении можно заменить одной. По моему, сугубо субъективному мнению, именно так и нужно поступать. Согласование двух React точек входа сложнее потому, что нужно согласовывать:
1. Обе React точки входа между собой
2. Первую  React точку входа с приложением
3. Вторую React точку вохода с приложением

Для каждой из этих 3х задач придется писать свои велосипеды.

Если оставить всего одну точку входа React в проложении, то согласовывать нужно будет только одну эту точку с приложением — и все. Причем это решение будет очень близким к конкретному куску документации React.

Я трижды решал эту задачу разными способами. Лучшее решение (последнее) — это одна точка входа.

Как вы собрались заменять две точки одной, если первая из точек входа — "шапка" страницы, а вторая — контрол выбора даты на форме фильтрации?

UFO just landed and posted this here

Ну хорошо, но у вас контрол выбора даты будет частью шапки сайта — или шапка сайта будет частью контрола выбора даты?


Как по мне, так в любом случае какая-то чушь получается.

UFO just landed and posted this here

И для того, чтобы достать дату из контрола, нужно будет обращаться к этому самому элементу? А если контролов выбора даты — несколько экземпляров — то ещё и уникальные идентификаторы для каждого надо выдумывать?

UFO just landed and posted this here
Вот тут и начинается то самое "согласование всех частей приложения"...

… которое ваши порталы лишь усложняют.


Ну и вообще, желание "достать данные из компонента", как то противоречит реактивной модели разработки с Unidirectional Data Flow.

А где вы в моём комментарии вычитали что-то про Unidirectional Data Flow и общий state всего приложения?


В ситуации, когда вы вынуждены размещать React-компоненты на "чужеродной" странице, у вас вообще в принципе не может быть никакого глобального состояния React-части приложения. Компоненты должны быть изолированы друг от друга и точка. Можно их даже в web component упаковать для большей красоты.

UFO just landed and posted this here
Да, верно, с испльзованием порталов

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

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

UFO just landed and posted this here
Очевиднее в каком смысле? Возможно, очевиднее с точки зрения внутренней реализации. Но мне в момент разработки не очень важна внутренняя реализация, мне важна наглядность. Как по мне, hooks нагляднее и лаконичнее. Все мы любим простой понятный лаконичный код. Хуки позволяют добиваться этого с меньшим количеством усилий.
Stateful компоненты (классы) хуже hook-ов

Уже какой-то фашизм от функциональщиков. Вы пробовали создать действительно сложные приложения stateless-компонентами? Я пробовал, на нескольких проектах, с коллегами очень высокого уровня (Яндекс, UBS), потом тоже самое переписывали на ООП с уменьшением сложности приложения раза в три. Фронтенд должен быть statefull, в этом как бы идея Rich Internet Applications. Чтобы поддерживать фрактальную природу программы во фронтенд компоненты обязаны иметь состояние и инкапсулировать сложную логику внутри, не пуская вне, иначе или будет коллапс сложности или функционал будет бедным, возникнут проблемы с масштабированием приложения вглубь. Facebook делает социальную сеть, у них возможно есть хорошие психологи, маркетологи, но у них нет хороших фронтенд-специалистов, они в этом вопросе не авторитет. Хватит за ними их бред повторять.

P.S.: И вообще не в их интересах, чтобы интернет рос, в их интересах, чтобы люди сидели не на разнообразных сайтах, а в facebook. Они создали Redux и сами не используют его. Они создали React с кучей архитектурных проблем и медленной разработкой и вложили кучу денег в пиар, хотя он не приносит им денег. Ничего не хочу сказать, просто странно, учитывая природу их основного бизнеса.
Да, интересные мысли. Тоже об этом задумывался. Но тогда Angular и Vue выполняют похожие задачи.

Я в последнем приложении (оно вполне себе большое) начал повсеместно использовать hooks, — и это моей команде дало возможность проще переиспользовать повторяющиеся куски кода (ранее для этих целей мы использовали HOC, что было гораздо менее наглядно и понятно). Покрывать тестами hooks, проще чем HOC-и. Опять же, все это субъективно.

По поводу заговора, тоже согласен. Он вполне может быть. Хотя я больше верю в благие намерения, не компаний, но разработчиков.
Angular первой версии имел проблемы со слишком слабой инкапсуляцией, поэтому большие приложения на нём было сложно разрабатывать, но простые делались на ура. Не скажу за более новые версии, не работал, но уверен Google знает что делает. Vue это просто песня, сочитает простоту первого Angular и стабильность React. Его часто позиционируют как фреймворк для стартапов, но мы использовали его в энтерпрайз и тоже очень довольны. По субъективным ощущениям разработка идёт раза в два быстрее, чем на React, код более декларативный, поддержка проще, вид и логика разделены by design, много приятного синтаксического сахара. Если бы не повальный пиар React и распространённость в компаниях — я бы только на Vue и программировал.
По сравнению с React Vue все еще слабоват. Те задачи, которые давно решены для React и Angular, все еще открыты для Vue. Наличие разных вариантов возможности разработки на Vue заставляет тратить время на выбор вариантов. В этом плане круче всех Angular. React что-то среднее в этом плане
Разные варианты это же замечательно. Вы можете писать в html-стиле или jsx-стиле. Можете использовать data или vuex. Выбор решения зависит от задачи. Гораздо хуже, когда создатели инструмента думают, что лучше вас знают вашу задачу и потребности и пытаются пропихнуть одно решение для всех случаев.
Буквально сегодня пытался отключить a11y lint в react-script 3.0, так как у нас внутренний проект и accessability только съедает время. Вы знаете, что в react-script это невозможно? Точнее вы можете отключить проверку, но сам пакет всё равно будет устанавливаться, причём дважды, и выбрасывать ошибку при билде, если этот неиспользуемый пакет отсутствует. Во Vue даже близко таких проблем нет. Я бы поспорил какой проект более слабоват. React даёт прямой путь для новичков, но как только вы пытаетесь его хоть немного кастомизировать — вас ждут преключения. Я считаю, что это нормальный подход для пользовательского продукта, которым пользуются бабушки, но недупустимо для профессионального.
Да, согласен. Пожалуй, react-scripts — это самое слабое место ReactJS. Я до сих пор не понимаю, как можно тащить столь отвратительный код такое долгое время. Полно есть альтернативных вариантов с нормальной архитектурой. Надеюсь, что это исправят в скором времени. Я и сам готов заняться этой задачей, если буду уверен, что обновление примут…

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

Хуки != отсутствие состояния. Хуки это другой API для хранения состояния компонентов. Моя практика показала, что в подавляющем большинстве случаев компоненты на хуках не сложнее классовых компонентов и хуки позволяют намного красивее декомпозировать и переиспользовать код компонентов.

Мне тоже больше нравятся хуки
UFO just landed and posted this here
Написание собственных библиотек, вместо существующих с открытым исходным кодом

лучше заменить на — «Лень поиска уже готовых решений, взамен проработки своих велосипедов», да и что таить, порой эти «готовые решения с открытым исходным кодом» настолько ужасны, что проще свое написать(можно заметить как особо ленивые авторы тупо делают PR в свою репу, особо не заморачиваясь, что там внутри, главное решает проблему).

Да, эдакая странная лень, которая силы не экономит, а наоборот, расходует впустую. Много таких. Я и сам таким бываю… Особенно, когда устал думать )
Кроме красоты кода открытых решений, нужно смотреть сколько народа их используют. Чем больше, тем, понятное дело, лучше. Так как баги, которые в своей либе еще зреют, они уже нашли и пофиксили. Был подобный опыт, когда товарищ не захотел использовать стандартную библиотеку для работы с датами и гордо написал свою — а про 29 февраля не подумал. Ну и сделал банальный день веселым :)
извиняюсь, что так поздно. Но к примеру в моем случае, я пишу энтерпрайз. Пришел к выводу, что лучше работать как команда VK. Скачать либу к себе, разобрать и модифицировать под свои нужды. Дело в том, что приходится писать экзотические вещи, которых либо нет, либо они реализованы не так, как нужно тебе. А когда ты пишешь автору свой PR с новым функционалом, ему такое не нравится и подобное пропускают. Так возникают новые проекты и кол-во человек в открытых решениях, порой не имеет значение, они просто популярны, не более, код в них может быть такой-же отвратный и плохо кастомизируемый.

Ну, куда это годится? Топ 5 ошибок = 1 очевидная ошибка + 1 холиворный топик + 3 ни разу не ошибки.


А как же сломанный асинхронный setState? А бесконечный ре-рендер из-за сайд эффектов в функции рендеринга? А разные версии реакта из-за ошибок бандлинга? Забыли про key=i в map()? А то, что функциональные компоненты ни разу не PureComponet? Куча же всякой неочевидной фигни в реакте (я люблю реакт не меньше вашего)!

Старался написать что-то новое, но, скорее, склонен с вами согласиться, чем оспаривать очень близкие к истине вещи. Хоть я и искренне считаю hooks лучше компонентов-классов.
2 Использование анонимных функций в качестве props

В этом пункте не хватает маленькой и очень важной детали: этот совет имеет смысл только если компонент, в который передаётся функция, мемоизирован (например, с помощью React.PureComponent или React.memo). Иначе рендер будет производиться в любом случае и описанный финт не поможет.


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

Спасибо. Проверю и поправлю статью, если все, что написано подтвердится на практике

С приходом хуков жизнь стала веселее, но сложнее. Каждый раз решая очередную неочевидную задачу я сталкиваюсь с головоломкой. Как бы мне эдак накрутить useEfect-ов, useRef-ов и useState-ов, чтобы они решали оптимально поставленную перед ними задачу. Чтобы нигде не "поехали" замыкания, чтобы непропустить какой-нибудь dependency и не создать этим страшно неочевидный и сложноотлавливаемый баг. Чтобы обезопасить себя от setState-ов после unmount-инга компонента. Чтобы не поломать ссылочную целостность и не потерять доступ к свежей версии переменных в замыкании. Это всё страшно интересно, но совсем непросто. Пока были pureComponent классы многие вещи реализовывались тривиально. А теперь это головоломки. Мне нравится.


Но… почему многие говорят что hook-и проще? :) Вот попробуйте на досуге решить хотя бы простую задачу: написать хук useIsUnmount, который позволит вам узнать отмонтирован компонент или ещё нет. Решается в 5-8 строк… но требует нестандартного подхода (useRef).


Ну или например решили вы создать очередной eventHandler и задействовали useCallback, задали ему правильных dependencies. Всё работает. Но если ваши dependencies меняются слишком часто — вы слишком часто пересоздаёте eventHandler и пере-render-ите древо ниже по курсу. А нужно ли это вам? Ведь eventHandler-ы для event-ов, а не для render-а. Ок, можно снова взять useRef. А нужно ли? Тут уже можно устроить холивар.


Итак во всём. Есть задача — начинаешь думать и видишь много путей решения. Какой правильный? Какой hook-way лучше, какой хуже? Нам дали довольно низкоуровневые инструменты построения реактивности, и теперь мы с ними можем столько говнокода нагородить, который будет стрелять в самые неочевидные моменты жизненного цикла приложения… Могу привести пример.

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

У меня линтер отлавливает неверные зависимости.

Все проблемы, о которых вы пишите были и раньше, просто вы их не замечали под капотом. Он просто ждали своей очереди…
Вы пишите о разных вариантах решения задач. Вы знаете ответы. У вас их много

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


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

Да то разве проблемы. Потеря this, разбросанная по коду класса логика (т.к. нет миксинов), всякие мемоизаторы\селекторы\линзы и с хуками есть. Не знаю даже. С классами было может и неудобно, но довольно просто. Разрулить потерявшийся this и разрулить поехавшее замыкание это задачи разного порядка.


У меня линтер отлавливает неверные зависимости.

Только простые случаи могут хоть как-то быть отловленными линтером. В этом случае вы можете его просто вообще заменить на useAutoCallback и вообще забыть...

Меня немного подергивать начинает, когда начинают писать про некий абстрактный «бизнес», который почему-то должен решать. Бред это. Не должен. Бизнес для людей. Интерес к разработке, — тоже для людей. Если разработчику не нравится его работа — он не сможет сделать ее хорошо. Так что, бизнес что угодно может решать, если разработчикам будет неинтересно работать с технологиями, которые продиктует бизнес — загнется такой бизнес.
НИКОГДА не передавать в качестве пропса компоненту анонимную функцию.

преждевременная оптимизация в полный рост.


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

в случае если компонент не использует ни memo(), ни PureComponent, он все равно перерендерится, даже если все пропсы равны. В этом примере в консоли видно, что при измении текста компонент без memo все равно ре-рендерится, несмотря на то что count не меняется.


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

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

Ну это смотря как подходить к процессу создания приложения. Мне лично проще не создавать узких мест и везде использовать memo/selectors/dependencies-for-hook/etc. Это мало чем отличается от написания приложения в лоб. И да, просто анонимные функции при этом (обычно) — зло.


К реальным оптимизациям (которые могут быть преждевременными) можно отнести вопросы архитектуры, какие-нибудь кастомные хуки для redux-а (к примеру древовидный connect), сложные древа селекторов, линзы, трансдьюсеры и прочие хитрости. А обыкновенные memo сложно назвать преждевременной оптимизацией.


ИМХО.

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

Качество материалов по React обычно очень низкое. Полностью поддерживаю. Причём как у нас, так и в английском интернете. Что не статья, то epic fail.

В чем проблема? Напишите материал высокого качества. С удовольствием почитаю. По поводу memo — спасибо за дополнение.

Думаю лучше всего начать с документации. Первым же делом года 3 назад я просто прочёл от корки до корки всю документацию React, Redux, а чуть позже Reselect. Это сняло 95% вопросов и очень сильно упростило жизнь. Почти все ошибки и непонимание React кроется в том, что народ учится по простым статьям не вдаваясь в детали того, как и почему оно там работает.


Если вы в какой-то момент поставите перед собой вопрос: "а могу ли я за неделю сам написать свой упрощённый react", и ответите на него утвердительно, значит вы прочитали документацию внимательно :)

Не того поблагодарил за memo. Спасибо
Пробую создать локально такой же пример — у меня нет разницы между memo и не memo… Возможно, я что-то неверно понимаю. Можете скинуть информацию на более развернутое объяснение, как это должно работать?

Вся информация есть в документации. Я решительно не понимаю почему её никто не читает...


Суть простая: все компоненты по-умолчанию всегда рендерятся со всеми подкомпонентами. Всё древо целиком. Не важно при этом одинаковые props вы передаёте или всё время разные. react ничего не проверяет и рендерит vdom-tree целиком. Всё поддрево. И для того чтобы этого избежать — необходимо давать react-у понять когда этого можно избежать. Все ссылки выше об этом. Но это только самая вершина айсберга. Настоящие immutable SPA пишутся куда более замороченно, чем просто понатыкать везде мемошек )

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


return (<div className={cls}  ref={n => this.wrapper = n} data-uat="scarousel"></div>)

в следующий вызов


return (React.createElement("div", { className: cls, ref: function (n) { return _this.wrapper = n; } }));

Как анонимная функция из props.ref хранится в памяти больше чем одним экземпляром, если это одна и та же функция в дереве кода?
Как тут может быть утечка? Обьясните пожалуйста.

А вы не путайте функцию в дереве кода и функциональный объект в JavaScript. Второй, согласно спецификации языка, создаётся новый каждый раз когда вычисляется функциональное выражение.

Sign up to leave a comment.

Articles