Comments 57
Написание собственных библиотек, вместо существующих с открытым исходным кодом
Хмм и откуда по вашему взялись все эти библиотеки (тут список из вашего package.json), как и сам React?
вместо существующих
Речь скорее про велосипеды.
Angular — велосипед
Vue — велосипед рожденный под впечатлением от Angular
React — велосипед, в его JSX это «огрызок» от E4X
Весь OpenSource чей-то велосипед, которым кто-то поделился, либо из-за отсутствия (вероятность чего сейчас нулевая), либо из-за того, что он устал от текущих решений, которые за годы превратились в монстров и просто устарели технологически.
Нет «всё», вы просто не понимаете простую истину, если бы в своё время, эти инструменты не были вынесены на суд общественности как opensource, они никогда не смогли превратиться из обычного местечкового велосипеда в то чем они стали.
эти инструменты не были вынесены на суд общественности как opensource, они никогда не смогли превратиться
«Суд общественности» рукоплескал еще одним яйцам в профиль или у нее были какие-то киллер-фичи, которые общественности полюбились?
как opensource
Вопросы лицензии — это вообще ортогональное понятие. Есть море проприетарных решений, которые пользуются популярностью.
«Суд общественности» рукоплескал еще одним яйцам в профиль или у нее были какие-то киллер-фичи, которые общественности полюбились?
По началу, сообщество очень и очень холодно приняло тот же React или Angular 2. А если б в Vue был менее сырым и за ним стоял бы не никому неизвестный «чувак», а какая-нибудь крупная компания, то кто знает, какая бы расстановка сил была бы сейчас.
Верное замечание, но необязательное. Хорошие библиотеки, получаются из реального боевого опыта и «набитой руки» в написании этих велосипедов.
ps Сейчас, кстати, настало новое время, когда как раз хорошо не брать готовое, а создать новое, т.к. очень много новых технологий появилось, js больше не стоит на месте и развивается с каждым годом, поэтому можно делать велосипед с заделом на бедующее.
Пожалуйста, не пытайтесь запихнуть на одну страницу больше одного экземпляра React приложения. [...] оптимизация такого подхода и согласование всех частей приложения, в этом случае начинает занимать больше половины всего рабочего времени
А что именно тут надо оптимизировать и согласовывать?
В моём представлении, несколько экземпляров React на странице возникают в ситуации, когда нужно разместить React-компонент на странице, построенной по другой технологии (angular, vue или даже jquery). Разумеется, в таком случае согласование компонентов отдаётся на откуп этой самой другой технологии — и не может быть проще чем согласование двух обычных компонентов на этой технологии. Но и сложнее оно не становится просто из-за того, что React-компонентов на странице стало аж два!
1. Обе React точки входа между собой
2. Первую React точку входа с приложением
3. Вторую React точку вохода с приложением
Для каждой из этих 3х задач придется писать свои велосипеды.
Если оставить всего одну точку входа React в проложении, то согласовывать нужно будет только одну эту точку с приложением — и все. Причем это решение будет очень близким к конкретному куску документации React.
Я трижды решал эту задачу разными способами. Лучшее решение (последнее) — это одна точка входа.
Как вы собрались заменять две точки одной, если первая из точек входа — "шапка" страницы, а вторая — контрол выбора даты на форме фильтрации?
Ну хорошо, но у вас контрол выбора даты будет частью шапки сайта — или шапка сайта будет частью контрола выбора даты?
Как по мне, так в любом случае какая-то чушь получается.
И для того, чтобы достать дату из контрола, нужно будет обращаться к этому самому элементу? А если контролов выбора даты — несколько экземпляров — то ещё и уникальные идентификаторы для каждого надо выдумывать?
Вот тут и начинается то самое "согласование всех частей приложения"...
… которое ваши порталы лишь усложняют.
Ну и вообще, желание "достать данные из компонента", как то противоречит реактивной модели разработки с Unidirectional Data Flow.
А где вы в моём комментарии вычитали что-то про Unidirectional Data Flow и общий state всего приложения?
В ситуации, когда вы вынуждены размещать React-компоненты на "чужеродной" странице, у вас вообще в принципе не может быть никакого глобального состояния React-части приложения. Компоненты должны быть изолированы друг от друга и точка. Можно их даже в web component упаковать для большей красоты.
Stateful компоненты (классы) хуже hook-ов
Уже какой-то фашизм от функциональщиков. Вы пробовали создать действительно сложные приложения stateless-компонентами? Я пробовал, на нескольких проектах, с коллегами очень высокого уровня (Яндекс, UBS), потом тоже самое переписывали на ООП с уменьшением сложности приложения раза в три. Фронтенд должен быть statefull, в этом как бы идея Rich Internet Applications. Чтобы поддерживать фрактальную природу программы во фронтенд компоненты обязаны иметь состояние и инкапсулировать сложную логику внутри, не пуская вне, иначе или будет коллапс сложности или функционал будет бедным, возникнут проблемы с масштабированием приложения вглубь. Facebook делает социальную сеть, у них возможно есть хорошие психологи, маркетологи, но у них нет хороших фронтенд-специалистов, они в этом вопросе не авторитет. Хватит за ними их бред повторять.
P.S.: И вообще не в их интересах, чтобы интернет рос, в их интересах, чтобы люди сидели не на разнообразных сайтах, а в facebook. Они создали Redux и сами не используют его. Они создали React с кучей архитектурных проблем и медленной разработкой и вложили кучу денег в пиар, хотя он не приносит им денег. Ничего не хочу сказать, просто странно, учитывая природу их основного бизнеса.
Я в последнем приложении (оно вполне себе большое) начал повсеместно использовать hooks, — и это моей команде дало возможность проще переиспользовать повторяющиеся куски кода (ранее для этих целей мы использовали HOC, что было гораздо менее наглядно и понятно). Покрывать тестами hooks, проще чем HOC-и. Опять же, все это субъективно.
По поводу заговора, тоже согласен. Он вполне может быть. Хотя я больше верю в благие намерения, не компаний, но разработчиков.
Буквально сегодня пытался отключить a11y lint в react-script 3.0, так как у нас внутренний проект и accessability только съедает время. Вы знаете, что в react-script это невозможно? Точнее вы можете отключить проверку, но сам пакет всё равно будет устанавливаться, причём дважды, и выбрасывать ошибку при билде, если этот неиспользуемый пакет отсутствует. Во Vue даже близко таких проблем нет. Я бы поспорил какой проект более слабоват. React даёт прямой путь для новичков, но как только вы пытаетесь его хоть немного кастомизировать — вас ждут преключения. Я считаю, что это нормальный подход для пользовательского продукта, которым пользуются бабушки, но недупустимо для профессионального.
Однако, что касается самих решений, тут React чуточку впереди. Библиотек больше и среднее качество их лучше. По крайней мере для тех задач, с которыми я успе столкнуться на обоих фреймворках
Хуки != отсутствие состояния. Хуки это другой API для хранения состояния компонентов. Моя практика показала, что в подавляющем большинстве случаев компоненты на хуках не сложнее классовых компонентов и хуки позволяют намного красивее декомпозировать и переиспользовать код компонентов.
Написание собственных библиотек, вместо существующих с открытым исходным кодом
лучше заменить на — «Лень поиска уже готовых решений, взамен проработки своих велосипедов», да и что таить, порой эти «готовые решения с открытым исходным кодом» настолько ужасны, что проще свое написать(можно заметить как особо ленивые авторы тупо делают PR в свою репу, особо не заморачиваясь, что там внутри, главное решает проблему).
Ну, куда это годится? Топ 5 ошибок = 1 очевидная ошибка + 1 холиворный топик + 3 ни разу не ошибки.
А как же сломанный асинхронный setState? А бесконечный ре-рендер из-за сайд эффектов в функции рендеринга? А разные версии реакта из-за ошибок бандлинга? Забыли про key=i в map()? А то, что функциональные компоненты ни разу не PureComponet? Куча же всякой неочевидной фигни в реакте (я люблю реакт не меньше вашего)!
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.
Думаю лучше всего начать с документации. Первым же делом года 3 назад я просто прочёл от корки до корки всю документацию React, Redux, а чуть позже Reselect. Это сняло 95% вопросов и очень сильно упростило жизнь. Почти все ошибки и непонимание React кроется в том, что народ учится по простым статьям не вдаваясь в детали того, как и почему оно там работает.
Если вы в какой-то момент поставите перед собой вопрос: "а могу ли я за неделю сам написать свой упрощённый react", и ответите на него утвердительно, значит вы прочитали документацию внимательно :)
Вся информация есть в документации. Я решительно не понимаю почему её никто не читает...
Суть простая: все компоненты по-умолчанию всегда рендерятся со всеми подкомпонентами. Всё древо целиком. Не важно при этом одинаковые 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. Второй, согласно спецификации языка, создаётся новый каждый раз когда вычисляется функциональное выражение.
Топ 5 ошибок в моих ReactJS приложениях