• Профессия: фронтенд-разработчик
    +1

    Потому, что когда вырастаешь в юниора, то начинаешь понимать, что TypeScript — это костыли для стажёров, а для вырастания в ведущие надо уже понимать, что плыть против течения себе дороже. Все побежали, и я побежал. ;)

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

    Может. Но это сторонние для вас сервисы. Этот замусоленный уже до дыр пример с Adblock был о другом: представьте, что у вас в своём облаке, своих контейнерах, своих сборках и своей JVM всё открыто нараспашку и можно внедрить любой сторонний код. Ну т.е. вообще любой, и в любой момент.


    А если мы вдруг курс валюты не проверим (по эвристикам и прочим ИИ) перед совершением транзакции — можно влететь на десятки миллионов евро.

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


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


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

    Эту старую песню о главном можно продолжать очень долго, но front end это не только визуализация данных.


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

  • Справочник по собеседованиям для тех программистов, которые их не понимают
    0

    Да ну ладно, о чём вы в самом деле? О какой анонимности тут речь идёт, когда товарищ авторитарно так заявляет, что его нужно слушаться ну вот нипочему? Мне просто любопытно, что это за птиц такой, всезнающий, всеумеющий и в истину в последней инстанции вхожий. А то чем чёрт не шутит, соберёшься этак собеседоваться в $куда-нибудь, а там как раз слушаться надо. А пацаны-то и не знали.


    Что касается профиля на этом сайте, то мне он не настолько важен, чтобы время тратить. Какое там качество аргументации, хабр это наискось за обедом полистать и языком почесать между делом, пока код в голове варится. А если вам интересен мой профиль, то в гугле вторая ссылка на мой полудохлый бложек, а четвёртая на Github. В отличие от, кстати.

  • Справочник по собеседованиям для тех программистов, которые их не понимают
    0
    А с этим всё проще — меня не нужно слушаться если со мной не работать. А если работать — то вопрос, как бы, отпадает.

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


    Страна должна знать своих героев. :)

  • Справочник по собеседованиям для тех программистов, которые их не понимают
    0
    Но ведь бывает и так, что бэк — это сотни а то и тысячи задач,

    Бывает, конечно бывает. И так бывает, и сяк бывает, хаос и энтропия никого не оставят в покое. Просто я всё время наблюдаю со стороны, как жизнь идёт у наших back end/platform/devops товарищей, которые всё время ужа с ежом скрещивают… Спокойнее у них там, гораздо. :)


    Иногда даже подумываю, а не плюнуть ли на всё, натянуть Golang какой-нибудь на голову и податься через забор. Но скучно там всё же, когда привык к адреналину, размеренная жизнь как-то не цепляет уже. Да и плюшки с этой стороны вкуснее. :)

  • Справочник по собеседованиям для тех программистов, которые их не понимают
    0
    Вы меня не поняли. На бэке неконтролируемые условие — это тоже обыденность, и по влиянию они точно такие же, как и adblock. Где-то кто-то что-то поменял и больше оно у вас не работает.

    В таком случае я не вижу, как это противоречит заявлению "front end это хаос". Даже более: поздравляю, у вас тоже хаос. :))


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

    Дался вам этот adblock, это просто один пример был. :) Мысль-то была очень простая: в front end разработке настолько часто встречаются неконтролируемые изменения условий, приводящие к кардинальным изменениям в софте и процессах, что это является нормой вещей. Делали приложение для десктопа и современных браузеров? Поздравляю, мы вчера подписали контракт на $1005000 с XYZ и им надо IE11. Упс, а Chrome пять минут назад обновился и теперь скроллинг не работает, срочно фиксить. А что, у вас сайт на телефонах не работает? Какая разница, что в ТЗ было, это вчера было! Что? Гугл поднял расценки на внедрённые карты, а у нас на них весь интерфейс завязан?


    Ну и т.п. Куда уж тут до чуточку недопереоптимизированных алгоритмов, выкатить бы что-нибудь. :)


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

    Я вам даже больше скажу: так вообще везде. Помнится, в начале 2000х, когда ВТБ по случаю прикупил себе Гута-банк, мне пришлось разворачивать колл-центр ВТБ24 с оборудования Гуты, но на площадке ВТБ. Сроки сжатые, нужное количество E1 пробросить не успевали, поэтому можно было только Voice-over-IP, новинку по тем временам. За неделю прошли все инстанции (в ВТБ! представляете?!), всё подписали, всё согласовали — стыковали сети, пограничку настроили, всё работает. Ещё за неделю телефоны развернули, сценарии прописали, всё готово к сдаче.


    А потом накануне запуска безопасники ВТБ такие: а мы тут вот затылок почесали, короче, не нравится нам RTP этот ваш, небезопасный он. Вы там что-нибудь придумывайте, а мы вам порты на файрволле зарубили. Всего хорошего.


    Вот 15 лет назад было, а до сих пор помню. Потому что такое резкое и несовместимое с разумом изменение внешних условий всё же не такое частое явление… Вне front end. :)


    Поверьте, любая третья сторона создает абсолютно одинаковые проблемы, хоть адблоком она называется, хоть админом Йоханом из Дели, хоть юзером Мартой из Бостона.

    Да ладно, ну что вы в самом деле. Проблема же не в разнородности проблем, а в их количестве. Как кто-то когда-то сказал, Quantity is a quality of its own. :)


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

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0
    То есть форма перерисовывается вся при изменении любого одного контрола, потроха таблицы после Bind — тоже все разом.

    Так они и обязаны перерисовываться, потому что зависят от состояния ключей filter, page и limit. Напрямую зависят. Я не вижу, в чём здесь проблема.


    Чтоб перерисовывать только то, что меняется (как это и происходит в вариантах с MobX) — вам нужно тащить ViewModel вниз.

    Можно и утащить, если есть необходимость. Можно добавить кучу оптимизаций, чтобы не пересчитывать values каждый раз, мемоизировать формулу, например. Вопрос в другом: зачем? Если написанное в лоб, за 10 минут, решение работает с адекватной скоростью, зачем мне тратить ценное время на предварительные оптимизации? Будет проблема, будем решать.


    ЗЫ: Вы, конечно, можете сказать, что перерисовывать 4 инпута вместо одного — это фигня и нестрашно, но то же самое справедливо и для MobX — эту же форму можно нарисовать обычным реактом, не трогать (на этом уровне) MobX и не написать ни одного лишнего слова в коде.

    Во-первых, именно так и скажу: если перерисовка 1000 компонентов <tr>...</tr> в таблице отрабатывает за ~18 мс, то перерисовка 4 полей тоже проблем не вызовет. Да хоть 20.


    Во-вторых, конечно эту форму можно нарисовать на ванильном React, вообще без MobX. Но а) не за 10 минут, б) не декларативно, в) доступ к данным будет ручками. А ручками как раз очень не хочется, потому что больно, чревато багами и тестировать трудно.


    Вообще давайте уже уточним, что я не продаю вам Statium как замену MobX в существующих проектах. Если у вас уже всё построено вокруг одного решения, то менять шило на мыло можно только, если причины очень весомые. Для существующих проектов они вряд ли найдутся.


    А вот как замена ванильному useState и хукам Statium даёт очень заметные преимущества. Это примерно как если пересесть с телеги на болид Формулы-1. Вы попробуйте как-нибудь, просто для расширения горизонтов. Вдруг понравится. :)


    Для меня, кстати сказать, опыт с RealWorld example был очень поучительным. Некоторые вещи оказались не такими удобными, как казалось при разработке библиотеки, но многое другое оказалось даже лучше, чем я предполагал. Надо ещё что-нибудь подобное замутить, dogfooding это всегда полезно...

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0
    Вот этот блок уже сам по себе уродство и адское нагромождение.

    Я смотрю, наша дискуссия уже окончательно пала до вкусовщины? Можем не продолжать в таком случае, всё равно бессмысленно.


    И это при условии что табличка то не из реальной жизни, у вас всего 3 колонки, в реальности их обычно 10 и больше.

    Да сколько угодно колонок может быть. Какая разница, сколько их? Я ведь говорил, что это пример, написанный за 10 минут. В реальном коде никто не мешает декомпозировать, использовать HOC или хуки. Три варианта, на выбор.


    Вы объединили тут 3 убогих подхода:

    Тут даже не знаю, что ответить. Вы в курсе, что Render props являются вполне официально рекомендованным подходом? Про остальные пункты я даже не слышал, вы их только что придумали наверное.


    Извините, но если вы в таком пренебрежительном тоне отметаете рекомендации разработчиков React, то либо потрудитесь предоставить веское обоснование, либо давайте закончим эту беседу.

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0
    В кратце так, mobx мутабельный и рекативный, вот почему) А React сам по себе имутабельный и не реактивный.

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


    Просто потому, что я в эту тему копал очень глубоко (нет, не в MobX, в прозводительность), и самый главный урок оказался простым: premature optimization is the root of all evil. ©

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0

    Вот смотрите, таблица с асинхронной загрузкой записей, фильтрацией и страницами: https://codesandbox.io/s/elated-buck-29fgg


    За 10 минут, да. Где адские нагромождения-то? :)

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0

    Woot! А я и в CodeSandbox, оказывается, могу: https://codesandbox.io/s/elated-buck-29fgg

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0
    Так вы сам код посмотрели?

    Да я-то ваш код смотрел. Это вам я никак не могу донести свою мысль, видимо плохо объясняю.


    Давайте попробуем вот так: https://codesandbox.io/s/xenodochial-snyder-hngmw


    Так зачем MobX-то? :)

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0
    Значит, заводите переменную в компоненте.

    Отлично, мы завели переменную в компоненте. Что это даёт? Ничего, всё равно надо подписываться на обновления вручную. Вот как в примере markelov69 ниже: создаём observable, скармливаем его в хук useState, и… Понимаем, что observable вообще не нужен, потому что хук сам по себе и решает вопросы хранения состояния и подписки на изменения этого состояния.


    Я что-то упустил?


    В ваших примерах вам state = {} написать не лень, а вот observable() написать — будет лень, так что ли?

    Дело не в лени, а в совершенно различной семантике. Объект, который вы передаёте в initialState, выполняет несколько функций:


    а) Задаёт список ключей с (потенциально) их типами
    б) Присваивает ключам значения по умолчанию, которые абсолютно необходимы для первого рендера (React синхронный, не забывайте!)
    в) Устанавливает ограничения на дальнейшие обновления состояния. Если вы не задали ключ в initialState, то установить его позже не получится, полетит исключение.


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


    Это очень сильно отличается от простого создания экземпляра observable в переменную, не находите?


    Конечно. Тут везде ровно одна механика — подписка на изменение, а как именно вы её выражаете — зависит от того, что вам нужно сделать.

    Так вот я эту механику никак не вижу в вашем примере с MobX — если, конечно, не делать её вручную. В чём и состоит суть моей аргументации: зачем вообще заниматься этим вручную? Зачем дублировать в каждом компоненте императивный код, когда можно вместо этого декларировать состояние и его отношение к вашим компонентам? И всё это делается очень легко, очень быстро и наглядно, без лишней писанины.


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


    В документации написано. В одно короткое предложение написано, кстати.

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


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


    Задавая вопрос в таком контексте — вы неизбежно придете к тому, что для формы с тремя полями вам не нужна ваша библиотека, вам не нужен MobX, и уж тем более вам не нужен реакт. Стейт-менеджмент вообще не имеет не малейшего смысла (любой), если вам «просто нужна форма с тремя полями». Стейт-менеджмент становится крайне полезен, когда у вас зоопарк разных контролов со сложной логикой взаимодействия.

    Вот тут, как мне кажется, мы стали нащупывать суть вопроса. Почему вам кажется, что для формы с тремя полями не нужно управление состоянием? Это не пассивно-агрессивная атака, мне в самом деле интересно, почему вы так думаете. Честно.


    Не потому ли, что в популярных библиотеках (Redux, MobX) управление состоянием делается настолько сложно, что временные и когнитивные затраты несопоставимы с результатом? И для простейшей формы с тремя полями проще не связываться, а сделать руками?


    Обратите внимание на популярность хуков. Почему сразу после их появления многие разработчики стали использовать их вместо Redux или MobX? На мой взгляд, именно по причине простоты использования: useState не требует никаких церемоний, создания констант-экшнов-редьюсеров-и-т.д., или классов с @observable, и т.п.


    К сожалению, у хуков очень много недостатков. Пресловутые Rules of Hooks, трудности с тестированием, трудности с доступом к состоянию из дочерних компонентов, потеря декларативности презентационных компонентов, масса ручной работы, потеря функциональной чистоты компонентов, случайные баги… Хуки useState и useReducer это не самый плохой компромисс, но всё же плохой.


    А у Statium ни одного из этих недостатков нет, и использовать ViewModel очень просто. Настолько просто и очевидно, что вопрос стоит уже по-другому: а какова может быть причина не использовать state management?


    Тем более такой, который позволяет совершенно безболезненно и за 10 минут масштабироваться от формы с тремя полями до таблицы с фильтрацией записей в реальном времени, например: https://gist.github.com/nohuhu/01a7bb42b1c1e1378ea0df6829799055


    Я не вполне понимаю ваш способ чтения, потому что в самом начале readme английским по белому явно написано, что mobx-react-lite может спокойно использоваться вместе с mobx-react.

    Первый абзац из документации mobx-react-lite гласит, что:


    Class based components are not supported except using <Observer> directly in class render method. If you want to transition existing projects from classes to hooks (as most of us do), you can use this package alongside the mobx-react just fine. The only conflict point is about the observer HOC. Subscribe to this issue for a proper migration guide.

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


    К тому же, если речь идёт о миграции с классов на хуки, то зачем вообще MobX? Я так до сих пор и не понимаю.


    А если почитать еще чуть глубже нормальным способом чтения, то там опять же явно написано, что mobx-react-lite вполне применим в классовых компонентах.

    Ещё раз, зачем мне читать глубже? Это вы предлагаете мне использовать MobX, потому что он гораздо лучше и проще моего решения. Я просто не понимаю, каким образом библиотека, которая фокусируется на других вещах (первый абзац из документации):


    "MobX in React brings easy reactivity to your components. It can handle whole application state as well."

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


    Ещё раз: я понимаю, что лично вам MobX нравится и кажется лучшим решением. А лично мне он не кажется даже просто хорошим решением. Слишком много усложнений для чего? Easy reactivity? Так мне оно не нужно (что бы это ни было), мне нужно форму с тремя полями. Или таблицу с фильтрацией.

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0
    Раз вы такое пишете, значит вы вообще не копали MobX и даже не пробовали его в деле

    Нет, в больших приложениях, построенных исключительно на MobX, не пробовал. Пробовал а) построить на нём мелкий проект, б) внедрить в большом проекте, где state management делался вручную на классовых компонентах и setState. В процессе копал достаточно (как мне показалось) глубоко, но скорее всего в какую-то другую сторону.


    Вот, прям сходу на коленке, codesandbox.io/s/admiring-ishizaka-ncsfk

    Брр, вы меня теперь уже совсем запутали. Если вы используете хук useState, то зачем вообще нужен MobX?

  • Справочник по собеседованиям для тех программистов, которые их не понимают
    0

    Нет, не то. Я не об этом говорю. Баги бывают, таймауты, переполнение базы, всё что угодно. Но это контролируемые условия. Есть проблема — вы её решаете, и всё работает взад. Баг можно пофиксить, базу можно подчистить или ещё ноду накатить, в сети QoS подвинтить или в чём там проблема была.


    В front end нормой жизни является непредсказуемое и неконтролируемое изменение условий. Вот как с тем примером с Adblock. Вы на самом деле ничего не делали, правда! — а оно бац, и поломалось. Совсем. И не починить, потому что юзера не заставишь отказаться от Adblock, а домен не убрать из списка. Это не баг и не проблема с сетью. Это именно изменение ТЗ, на лету, постоянно.


    Я же не пытаюсь выпендриться крутизной, я просто объясняю, что front end это очень особенная область в разработке софта. Тут царит хаос и непредсказуемость, которая требует выдержки и определённого склада характера. Если вам нравятся чётко поставленные задачи в CS стиле: ввод -> алгоритм -> вывод, а изменение ТЗ вызывает беспричинную раздражительность, то лучше во front end не заходить. Шишек набьёте, ЧСВ синяками покроется, и будете потом всем с умным видом рассказывать, какие они идиоты и как надо было всё делать вообще не так.

  • Справочник по собеседованиям для тех программистов, которые их не понимают
    0
    Зарплата была моим условием при заключении контракта, извините.
    Так с какого перпугу я должен перед этими людьми бить чечётку?

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


    Ну так если хотите — так и сделайте. Кто мешает? Вдавайтесь…

    Это очепятка была. Не хочу я вдаваться в эти подробности.


    с другой стороны — наблюдаю не работающий уже неделю в Firefox ESR 68.4 интерфейс перевода денег с карты на карты в Yandex.Money… ну и как это сочетается, извините?

    Да легко: кто вообще пользуется этим дурацким Firefox? Полтора пользователя, которые никому не нужны?


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

    Ваша самоуверенность вполне типична для back end разработчика, который заглядывал во front end пару раз, не осилил, и теперь делает очень категоричные заявления о том, что реально нужно для большей части сайтов.


    Нет, ну ей-богу, скучно. На том давайте и закончим, всего хорошего.

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0

    Это, кстати, тоже преимущество Statium: не нужно никаких церемоний, изменения архитектурных решений и т.п. Можно просто взять и попробовать его использовать для одной маленькой формы. А потом для двух. А потом для всего модуля. Или приложения. Или не использовать, а продолжать с Redux.


    И взаимодействие что с Redux, что с MobX сделать очень просто. По-моему, это большой плюс. Не находите?

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

    Навскидку, странный общий ключ у общего родителя и в Statium вполне сработает.


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


    В принципе горизонтальная сигнализация вполне возможна, но API для неё в рамках React придумать будет нетривиально. Я подумаю, задача интересная. :)


    Да запросто. У вас есть 50 записей чего-то + фильтр (ну или сортировка). И черт с самим фильтром, быстро работает, а вот сбрасывание shallow compare (ну или shouldComponentUpdate) — большая проблема. Нужны уже реселекторы всякие там, чтобы computed всегда возвращал одно и то же значение.

    Не уверен, что до конца понял постановку проблемы, но что-то подобное должно работать вполне быстро: https://gist.github.com/nohuhu/01a7bb42b1c1e1378ea0df6829799055


    Набросал за 10 минут, попробовал — при отображении 1000 записей фильтрация отрабатывает с едва заметной задержкой. В профилировщике самая медленная функция вне React — это FaaC в теле компонента Table, отрабатывает за 1.8 мс собственного времени. Это подход влоб, без оптимизаций.


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


    Или я всё же как-то неправильно понял задачу?


    Ах да, прошлый раз забыл: а что там по рефакторингу? Если я захотел переименовать user в profile — мне идти по всему коду и менять надпись? Селекторы как абстракция придуманы не просто так (в mobx это проще, потому что всегда прямая ссылка на поле, ts справится с переименованием).

    Не совсем понятно, что вы имеете в виду под селекторами. Если меняется имя ключа в модели, то конечно же нужно менять привязки. Как вариант, можно использовать HOC:


    import { withBindings } from 'statium';
    
    const withFoo = Component => withBindings('foo')(Component);

    В таком случае имя ключа надо будет менять только в одном месте.


    На практике, так ли часто это нужно? В наших проектах TypeScript не используется, и вроде проблем особых нет. Не то, чтобы я был так уж активно против TypeScript, просто стараюсь исходить из прагматических соображений: есть проблема — решаю. Проблем с рефакторингом пока не было, тесты решают всё. :)


    Нормализованных. Пример: у меня есть список всех лекций, а на панели слева список текущих лекций. Я переименовал одну лекцию — как панель слева узнает о том, что я это сделал?

    Если у вас данные в нормальном виде, то самый простой подход — использовать вычисленные значения для презентации, с помощью формул: https://github.com/riptano/statium#computed-values. Я как раз такой подход использовал в примере выше. При этом ничто не мешает хранить нормальные данные в родительской модели, а формулы декларировать в дочерних, по необходимости.


    Изменения в одном месте отражаются сразу во всем приложении. Только у меня таки "таблиц" в терминах БД 50+. И, как я сказал, если их хранить все в рутовом ViewModel, тогда он вырождается в редакс (только без тайм тревела, логирования, мидлвейров, саги).

    Ну, не совсем вырождается в Redux, хотя такой вариант возможен. У вас ведь приложение состоит не только из списка лекций? Есть какие-то другие страницы: календарь, пользовательский профиль, профиль студента, наверняка куча всего. Если вы абсолютно всё состояние приложения храните в front end, то может быть и имеет смысл хранить все данные в глобальной модели. А может и нет; в Redux у вас особо выбора нет, а в Statium есть.


    Что касается недостатков, то я не спорю, по фичам Statium очень далеко до Redux. Но и time travel, и logging вполне возможны, я планирую их добавить в какой-то момент. Просто инструментарий пока не в приоритете (дед лайн близко).


    А Middleware делается через applyState и контроллеры.


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

    Если для вас это недостаток, то можно не использовать. :) Глубокая выборка из структуры опциональна и сделана больше для удобства (пример). А так никто не мешает привязываться по ключу к структуре данных и ходить по ней явным образом.


    С архитектурной точки зрения, при unmount запросы должны отбрасываться либо их результат игнорироваться. Как минимум, не должно мигать пол страницы. Впрочем, тут только rxjs молодцом, с сагой еще можно извернуться, остальные технологии требуют достаточно больших телодвижений и спасает, что обычно данные в дочерних компонентах никому не нужны и факт их загрузки никому не мешает.

    Вот я как раз вчера думал на эту тему. И придумал вот что: можно отменять запросы через какое-нибудь новое API, но это чревато побочными эффектами. А что, если просто бросать исключение? Если родительская модель (или контроллер) отмонтирована, то попытка вызвать $get/$set/$dispatch бросит что-нибудь типа ComponentUnmountedError. А пользовательский код может это проверить и отреагировать, как надо — включая отмену сетевых запросов и т.п.


    Как думаете? Исключения в обработчиках всё равно надо ловить, так что дополнительная когнитивная нагрузка минимальна.


    Это приведет, со временем, к миграции всего в рутовый ViewModel. В лучшем случае, в рутовый для модуля, а не всего приложения.

    Может привести, а может и нет. Всё зависит от того, какое у вас приложение, с чем работает, и как. Вы же исходите из своей специфики, а я, например, из своей. Для того типа приложений, с которыми я работаю, хранение глобального состояния в клиенте нетипично; чаще нужно хранить локальную копию состояния в клиенте, и обновлять её с сервера/в сервер при навигации и прочих действиях пользователя. Зачем тут глобальная модель, в которой всё-всё-всё лежит?


    Вообще надо сказать, что с "толстыми" приложениями в web я отлично знаком — раньше работал над фреймворком Ext JS, который как раз для таких приложений больше использовался. И специфику хранения больших наборов нормализованных данных с моделированием отношений между ними я тоже знаю не понаслышке. :)


    … опять все всплывает вверх.

    Если всё всплывает вверх, то значит, это так нужно и логично. Не вижу противоречий. Просто исходя из моей практики, далеко не всё и не всегда всплывает вверх. Если локализовывать состояние в ViewModel, даже большое количество этого состояния, то получается такой мини-Redux для каждого модуля (страницы?). Ничего странного в этом нет.


    А вот когда она нужна, локализация состояния делается в Statium очень легко и просто. А в Redux не очень, поэтому обычно все и говорят, что она не нужна. :)

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0
    Ну come on, это просто переменная. Переменную можно объявить примерно где угодно, и передать примерно куда угодно.

    Вы с React работаете? Я не просто так спрашиваю, мне интересен MobX в контексте React. Вне этого контекста он мне не интересен.


    А в React просто переменная мало чем пригодится. Если вы её в модуле объявите, будет у вас один экземпляр observable, созданный в момент загрузки модуля. А компонент рендерится гораздо позже, что мне толку от такой переменной? А если мне надо два экземпляра такого компонента?


    Если у вас компонентный UI, то странно жаловаться, что надо, оказывается, эти самые компоненты делать, не?

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


    Вы же сами выше по ветке утверждали, что всё элементарно просто:


    И действительно, зачем? Что вам мешает сделать простой const model = observable({ бла-бла }) и залить туда всё нужное?

    Вот я и прошу уточнить, как именно этот подход использовать в React + MobX, чтобы было просто, наглядно и очевидно. Я с вами не спорю, а пытаюсь учиться. Очевидно, что моё MobX-fu не так сильно, как я думал.


    Очевидно же, что MobX этими вопросами не занимается — это просто реактивная библиотека. Как хотите, так и перерисовывайте — в общем случае это просто объявление reaction() или даже autorun() внутри компонента, который при изменении нужных свойств у обсервабла запустит перерисовку компонента. Это, собственно, именно то, что делает observer из mobx-react. Никакой магии тут нет.

    Если вам нужно это понимать — для этого и существует все эти reaction(), autorun(), или даже просто observe(). Обычная подписочная модель.

    Это, по-вашему, подпадает под определение "простой в использовании библиотект"?


    Например, чем отличается reaction() от autorun()? Как определить, в каком случае использовать то, а в каком другое? А если окажется, что я ошибся и случай не тот, а другой? Как менять одно на другое? Как тестировать, что при замене моя функциональность не сломалась?


    Зачем мне нужно знать, что MobX не занимается вопросами состояния компонентов в React, а для этого нужен react-mobx? Мне, блин, форму с тремя полями надо сделать.


    Я не знаю, как вы искали, потому что у меня поиск занял примерно 5 секунд — на то, чтоб набрать три слова и на то, чтоб гугл выдал результаты.

    Спасибо, я не догадался добавить hooks в поиск. Я искал "react mobx no class", и первый результат на StackOverflow указывает на то, что MobX хуки не поддерживает.


    Из ваших результатов видно, что уже (вроде бы?) поддерживает, но не сам MobX, а сторонняя библиотека mobx-react-lite, у которой есть конфликты с существующим кодом. Поддержка хуков планируется в MobX 6, но в официальном репозитории MobX нет упоминания версии 6.


    А если почитать чуть глубже, то начинаются ограничения: если хуки, то классовые компоненты нельзя. А если мне надо componentWillUnmount? Тогда старый MobX с классами, а он в хуки не умеет. Приехали обратно.


    Вот честно, я уже потратил ещё один час на более глубокое ознакомление с MobX, и этот час совершенно не приблизил меня к пониманию, каким образом React + MobX может быть проще в использовании, чем React + Statium.


    А форма с тремя полями? Засекайте время:


    import ViewModel, { Bind } from 'statium';
    
    const state = {
        username: '',
        email: '',
        password: '',
    };
    
    const FormWithThreeFields = () => (
        <ViewModel initialState={state}>
            <Bind props={[
                    ['username', true], ['email', true], ['password', true]
                ]}>
                { values => (
                    <form>
                        <input type="text" placeholder="User name"
                            value={values.username}
                            onChange={e => { values.setUsername(e.target.value); } />
    
                        <input type="email" placeholder="E-mail"
                            value={values.email}
                            onChange={e => { values.setEmail(e.target.value); }} />
    
                        <input type="password" placeholder="Password"
                            value={values.password}
                            onChange={e => { values.setPassword(e.target.value); }} />
                    </form>
                )}
            </Bind>
        </ViewModel>
    );
    
    export default FormWithThreeFields;

    … 3 минуты, это я опечатываюсь много.

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0

    Спасибо за критику! Нет, правда, мне очень интересны критические/негативные отзывы. Это возможность узнать о проблемах и быстрее их решить. :) Текущая версия библиотеки всего 0.2.3, ещё многое нужно решить! И API тоже можно менять, в разумных пределах. :)


    Далее по пунктам (без номеров, markdown странно работает в цитатах):


    Абстрагируясь от идеи вписывания бизнес-логики во вью

    Мне кажется, тут скорее проблема с подачей материала (с моей стороны, буду править). Бизнес-логика вписывается не в презентационный слой, а в ViewController. Это сама по себе отдельная сущность, которая занимается только асинхронной логикой. <ViewModel controller={...} /> это просто сокращение, чтобы отдельно ViewController не описывать (и сэкономить на отступах! :), а вообще ничто не мешает описывать логику вообще отдельно от всего, например так:


    import { ViewController } from 'statium';
    
    const MyController = ({ children }) => (
        <ViewController initialize={...} handlers={...} >
            { children }
        </ViewController>
    );
    
    export default MyController;

    … и использовать потом как изолированный компонент.


    Стоит убрать FaaC (function as a child) в пользу хуков. Сильно сократит и упростит код. В разы.

    Вы имеете в виду FaaC в компоненте Bind? Можно вместо него использовать хук useBindings:


    import { useBindings } from 'statium';
    
    const MyComponent = () => {
        const [foo, bar] = useBindings('foo', 'bar');
    
        ...
    };

    Что интересно, я тоже думал, что хуки сократят и упростят код компонентов. На практике оказалось, что мне самому существенно быстрее и проще использовать <Bind> и withBindings, хотя хук тоже иногда пригождается.


    Показал бы в примерах как это тестировать.

    Обязательно! Тестирование — это одна из сильных фишек Statium. К сожалению, я не могу показать код, который мы для тестирования боевых приложений используем, но обязательно добавлю примеры тестирования в RealWorld приложение. Просто не успел ещё, я его в прошлые выходные запилил по-быстрому. :)


    Как вызвать метод контроллера компонента сверху? Окей, диспатч или более странный способ через $set, допустим. К слову, в редаксе нельзя напрямую писать в store, никогда не задумывались почему?)

    а) Вызвать метод родительского контроллера: $dispatch.


    б) $set устанавливает значение в модели-владельце. Это не обязательно родительская ViewModel. $set карабкается по дереву, находит ближайшего владельца и устанавливает значение. Если какая-то из дочерних моделей переназначает ключ, то обновляться будет она (из низлежащих). Надо будет добавить инструментарий для отслеживания таких ситуаций.


    в) В Statium тоже нельзя напрямую писать в данные ViewModel, только через функцию-setter. При этом можно либо валидировать значения перед записью (applyState), либо полностью предотвращать запись и делать что-то ручное (protectedKeys + ViewController event handler). По умолчанию модель просто обновляет значение, потому что это самый частый случай.


    Как среагировать на изменение состояния соседа? А что если сейчас вам не нужно связывать две панели между собой и вы создали достаточно объемную ViewModel в каждом из них, а потом вдруг понадобилось их связать (они стали взаимно зависимыми)?

    Объединить оба компонента под родительской ViewModel и вынести связанные ключи в неё. Это безболезненно и очень быстро. :) И в смысле разработки, и в смысле производительности.


    Это одна из самых важных фич ViewModel: обновления состояния всегда ограничены минимально возможным регионом. Автоматически.


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


    У меня есть список пользователей. Каждый раз я открываю пользователя — я должен его догрузить. Но у меня еще есть N методов для каждого пользователя. Как вы это организуете в своем фреймворке? Каждый пользователь — отдельный ViewModel? А как тогда будете кешировать пользователей?

    Самый очевидный вариант — да, рендерить ViewModel на каждого пользователя. Я в примере так и сделал со списком статей, проблем с производительностью не заметил при N = 100. N = 500 ломает Chrome, но это почему-то происходит и без ViewModel на странице, я копать не стал (времени не было). Т.е. при рендеринге 100 ViewModel при профилировке этих вызовов вообще не заметно в Call Trace.


    Про кеширование не совсем понял, уточните?


    Продолжение 5-го пункта. У меня в реальном проекте более 50 доменных объектов (это мы еще плохо нормализовали данные). И они, к сожалению, достаточно сильно связаны между собой. У вас вырадится в редакс? Или будет иерархия из 50-ти вложенных контекстов?

    Тоже не совсем понял. 50 вложенных объектов, или просто связанных? В ViewModel можно хранить объекты, и вообще любые структуры данных. Селекторами можно лезть глубоко в структуру, как для чтения, так и для записи:


    import ViewModel, { useBindings } from 'statium';
    
    const initialState = {
        foo: {
            bar: {
                baz: 42,
            },
        },
    };
    
    const Component = () => (
        <ViewModel initialState={initialState}>
            <CounterButton />
        </ViewModel>
    );
    
    const CounterButton = () => {
        const [[baz, setBaz]] = useBindings([['foo.bar.baz', true]]);
    
        return (
            <button onClick={() => { setBaz(baz + 1); }}>
                Click me!
            </button>
        );
    };
    

    Никакой магии тут нету, кстати сказать, банальные lodash.get/set. Ну, и чуточку обвязки.


    Как "прервать" / отбросить / отменить асинхронный метод? Что если я уже успел покинуть viewModel, которое еще не успело что-то загрузить, при этом оно перепишет какое-то значение родителя?

    Вы мысли мои читаете? :)) Только час назад открыл этот тикет: https://github.com/riptano/statium/issues/13.


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


    С архитектурной точки зрения мне кажется, что таких штук допускать не надо. Данные надо держать близко к коду. На практике, конечно, нужно с этим что-то делать. Идеи приветствуются. :)


    Да, а вот вариант с перезаписыванием значения в родительской ViewModel мне в голову пока не приходил, спасибо. Т.е. в случае:


    const Parent = () => (
        <ViewModel initialState={{ foo: 'bar' }}>
            <Child />
        </ViewModel>
    );
    
    const Child = () => (
        <ViewModel initialState={{ bar: 'qux' }}
            controller={{
                handlers: {
                    event,
                },
            }}>
            ...
        </ViewModel>
    );
    
    const event = async({ $set }) => {
        await new Promise(resolve => { setTimeout(resolve, 10000); });
        $set('foo', 'baz');
    };

    … если event уже выстрелил, а потом Child демонтируется, то… хм… Надо тест написать, я не уверен, что произойдёт в текущем коде. Скорее всего значение foo изменится на новое, без ошибок.


    К слову, как в методе контроллера получить значение чужой viewModel?

    Если это родительская модель, то просто $get('foo') — все ключи вышестоящих моделей доступны детям (но не наоборот). Если это не родственная модель, то никак. Это фича. Выносите ключи в общего родителя.


    Самое главное: зачем это все, если есть useReducer и useContext, которые позволяют получить все тоже самое? Ну вместо $set будет у вас dispatch({type: 'set'}), обертку можно легко сделать.

    Так Statium и есть эта самая обёртка, чтобы вручную в каждом компоненте не писать. :) Точнее, первоначальная версия ViewModel была такой обёрткой, 100 строк кода с useContext и useReducer. А зачем? Чтобы управление состоянием вынести за скобки компонента и перестать им заниматься. И думать о нём. Вообще.


    Кроме этого: иерархический доступ к моделям. Этого вручную на хуках по-быстрому не сделать.


    Или вот для синхронизации состояния с URL, легко и непринуждённо: https://github.com/riptano/urlito.


    А ещё для метапрограммирования. Чтобы иметь компонент для динамического определения формата состояния компонентов, и обработки этого состояния. Одно из боевых применений в наших приложениях — компонент Report, который принимает объект с определением отчёта, полей, связей между ними, состояния таблиц, и т.д.; создаёт ViewModel и рендерит все дочерние компоненты. Очень удобно, когда встроенных отчётов 50+ в разных форматах, и нужно периодически добавлять новые.


    ViewController рождён в битве с back end и выкован в схватках с Apollo GraphQL. В какой-то момент back end сказало: ква, быстрее не можем. Грузите данные в tree grid порциями: сперва верхний ряд строк, потом догружайте по необходимости. Попытки выкрутить хуки GraphQL и сделать такую ступенчатую загрузку с промежуточными состояниями и маскировкой таблицы в синхронном коде довели меня до белого каления, я плюнул и добавил к ViewModel ещё и ViewController. А потом добился разрешения всё это выложить в open source. :)


    Это RealWorld приложение я слабал на коленке в прошлые выходные. Сам код Statium в тестировании уже более полугода, полёт номинальный. Скоро релиз. :)

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0
    Куда угодно.

    Можно пример? Я, видимо, недостаточно глубоко копал MobX, мне не очевидно, как такой подход использовать.


    Данные-то откуда? Из формы? Ну вот и складывайте где-то там, где у вас обработчики событий формы.

    Из формы или ещё откуда-нибудь. В вашем примере мы присваиваем значение переменной. Эту переменную надо где-то хранить, чтобы потом использовать в форме. Надо создавать класс для компонента, чтобы хранить this.model, или функциональный компонент. Тоже ручная работа.


    Но это всё ерунда, а вот как заставить компонент перерисовываться на изменениях модели? https://mobx.js.org/refguide/observable.html ни слова об этом не говорит, зато перечисляет аж 5 правил конвертации значений, которые нужно знать. И исключения для MobX версии 4, о которых тоже надо знать.


    Зачем? Чтобы сделать форму с тремя полями?


    Эм. Взять этот обсервабл и прочитать, что в нём?

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


    Где же? Примеры из документации mobx очень часто написаны без декораторов.

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


    Примеров с React без использования классовых компонентов я не нашёл. Плохо искал?

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0

    А куда вы этот код сделаете, и как будете вызывать, чтобы а) данные туда сложить, и б) данные оттуда вытащить? И когда?


    Нет, мне правда интересно. Почему-то во всех примерах с MobX используются именно классы и тонна магии. Почему?

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0

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


    Ну честно, вам когда форму с полями нужно сделать, зачем для этого нужно создавать класс, поля, методы для работы с ними, да ещё и обмазывать эти методы магией @observable? В Statium всё гораздо проще: вот модель (API), вот поля с данными (initialState), вот список, какие значения куда скормить (Bind). И всё.


    А если в форме нужно показывать значение из вышестоящего состояния? Имя юзера, например, или поле из родительского компонента. В Statium банальнейше, в MobX больно (ручками).


    Вы посмотрите пристальнее, вдруг понравится. От ненависти до любви один шаг. :)

  • Справочник по собеседованиям для тех программистов, которые их не понимают
    +1
    Это бизнес (или, вернее, менеджеры), который всё время «хочет странного».

    С точки зрения этого бизнеса (или, вернее, менеджеров), вы тоже всё время хотите чего-то странного. Зарплаты, например.


    Вот просто забить большой болт и всё.

    Я хочу вдаваться в подробности на тему, почему "забить большой болт и всё" нельзя. Это отдельная большая тема.


    Я вам о другом говорю: забить большой болт не работает. Можно забивать сколько угодно, это не поможет. Никак. Потому что у 95% пользователей всё равно будут разные браузеры, разные платформы, и разные устройства. От мощных десктопов до туповатеньких Chromebook, от последних iPhone до дешёвых китайских клонов какой-нибудь младшей модели Samsung Smartwatch. Какие критерии вы предлагаете использовать для исключения тех и этих, чтобы ваша жизнь была попроще? Назад в будущее, к This site is best viewed in IE6?


    По вашим словам мне очевидно, что вы просто не владеете предметной областью. Так и должно быть, front end не ваша специализация. Это моя специализация, и я отлично знаю из опыта и толстой мозоли на лбу, почему нельзя "просто взять и сделать" сайт, чтобы всё работало и все были довольны.


    Я стараюсь не вспоминать о битвах с нативным скроллингом документа, который есть сущее, адское зло — а виртуальный скроллинг это тоже сущее, адское зло. У меня в печёнках сидят поля ввода в HTML, обработка фокуса, маски и валидирование значений. Меня тошнит от touch events, от распознавания жестов по таймауту и ловли утёкших таймеров (ручками, всё ручками!). Я молча посылаю пламенные лучи ненависти и поноса в сторону HP, Lenovo и прочих умников, выпускающих лаптопы с тачскринами, которые никак особенно не определяются в браузере и потом к чертям ломают всю обработку событий, потому что смешать pointer events и touch events это — а чо, у нас в Windows работало? Я плачу кровавыми слезами каждый раз, когда мне нужно лезть в caniuse.com и подтверждать, какие фичи из CSS3 работают в последнем мобильном Сафари, а какие нет. И т.д. и т.п., конца и края этому нет (и не будет).


    Можно всё это игнорировать, для личных проектов сойдёт — кому они нужны, кроме вас. А для коммерческих проектов не сойдёт, и игнорировать уже не получится. Добро пожаловать в добрый, светлый мир front end. :)

  • Справочник по собеседованиям для тех программистов, которые их не понимают
    0

    Это всё же не совсем то, о чём я говорил. Прокси-сервисы и middleware тоже ломаются иногда, настройки слетают, и всё такое.


    Но в back end практически не бывает так, чтобы без каких-либо изменений в вашем коде/настройках/Dockerfile/K8s/whatever, вдруг внезапно всё сломалось и перестало работать.


    А на frond end — легко. Домен третьесторонней интеграции кто-то добавил в чёрный список, и привет. Узнать об этом, кроме как из разъярённых воплей обиженных клиентов, вообще никак нельзя. Это не хаос?

  • Справочник по собеседованиям для тех программистов, которые их не понимают
    +3
    Вы так говорите, как будто я front end не делал. Делал. И не раз. Нет там никакого хаоса.

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


    Если даже не вдаваться в поэзию, то самый поверхностный анализ ситуации позволяет увидеть, что благодаря наличию:


    • Различных браузеров, разных версий
    • Различных платформ и устройств
    • Абсолютно неконтролируемых сетевых условий
    • Абсолютно неконтролируемых условий среды в браузере

    … и т.д., и т.п., поверхность потенциально проблемной области в front end разработке в разы больше, чем в back end. Если не на порядки.


    Просто для примера, из свежего: у вас в практике часто бывало, чтобы на серверной стороне в код без спросу внедрился случайный третьесторонний модуль и начал блокировать вызовы к каким-либо микросервисам? И его не убрать никак. А у нас это норма жизни, ad blockers или какие-нибудь расширения в браузере могут в любой момент поломать что угодно. И объясняй потом бизнесу, почему их интеграция с каким-нибудь Appcues не работает и как её починить (а починить нетривиально).


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


    Мы из Хаоса (tm).

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0

    Вот странно, какие всё же плохие и громоздкие подходы вы имеете в виду… На мой взгляд, Statium гораздо проще и понятнее того же Redux, да и MobX тоже.


    А коллегам, между прочим, вполне понравилось. :)

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0
    Да, пардон, я не посмотрел исходники до конца, и не увидел, что оно всё заканчивается контекстами.

    Фух, спасибо, отлегло. А то я уже в исходники полез, вдруг что-то где-то течёт… :)


    Я не буду спорить за идеологию реакта (хотя бы потому, что не считаю её в принципе хорошей),

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


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


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

    Состояние это не компонент, состояние это просто набор данных. Компонентом является хранилище состояния, фактически это просто API для доступа к объекту с данными.


    Необходимо ли было делать это API в виде компонента? Нет конечно, есть и другие варианты; у этого же подхода есть как минимум одно большое преимущество: лёгкость использования в функциональных/презентационных компонентах. Гораздо проще и быстрее написать вот такой код:


    const Component = () => (
        <ViewModel ...>
            ...
        </ViewModel>
    );

    … чем функцию, которая что-то с чем-то соединяет, или @observable магию, которая рассыпается без поддержки декораторов, etc.


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

    Да, вы правы. В какой-то момент мне надоело бодаться с ветряными мельницами. If you cannot beat them, join them и всё такое.


    Тем более, что если допустить, что с какой-то точки зрения React вполне себе работает, то может, и ладно? Работает себе, давайте используем существующие механизмы. В конце концов, зарплату платят за фичи. :)


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

    Вполне возможно, что оно так выглядит из-за плохого изложения материала. Над документацией мне ещё работать и работать, это факт. Потому что с моей точки зрения, абстракций в ViewModel как раз почти нет: это тупо тот же самый setState, только вынесенный в отдельный компонент.


    И скорее всего это всё очень небесплатно для производительности.

    Понятно, раздел с анализом производительности надо поднять наверх. :) Я его в конец README засунул, так не работает.


    Вообще всё с точностью до наоборот: ViewModel работает безобразно быстро. Т.е. настолько, что я сколько ни пытался профилировать на работающих приложениях, ViewModel и сопутствующий код даже не заметно в Call Tree, надо очень глубоко копать.


    А если подумать, то чему там тормозить? Собственно данные ViewModel лежат в обычном объекте, который связан по прототипной цепочке с родительскими объектами. Чтение по ключу из объекта это как раз то, что JavaScript умеет делать очень быстро. :)


    Обновление состояния тоже ненамного дороже родного для React this.setState(). А поскольку ключ обновляется в модели-владельце, то рендеринг отрабатывает только для этой модели и её детей. Ну т.е. в самом худшем случае, если у вас абсолютно все ключи в одной модели в корне приложения, получаете такой как бы аналог Redux. :)


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


    А в Statium всё просто: каждая модель автоматически имеет доступ к родительским данным, и вы просто можете их использовать там, где нужно. И любимая проблема: упс, я задал ключ foo вот здесь, а он нужен ещё вон там в соседнем компоненте, решается банально переносом одного свойства в родительскую модель. И всё просто работает. :)

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0

    Спасибо за отзыв. :) Можно поинтересоваться, что именно вызвало у вас такую реакцию? Концепция хранения данных в компоненте, иерархическая связь, кривизна API, или код примера? Или всё вместе? Ну правда, интересно же. :)

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0

    Спасибо за критику, очень интересно. Можно по пунктам?


    Да, давайте в компоненты еще и модель затащим.

    А почему нет? Этот подход идеологически ничем не отличается от this.setState() в компонентах; практически разница только в том, что состояние делегировано в отдельный, предназначенный для этого компонент. Специализированность компонента позволяет решать проблемы доступа к данным без текущих абстракций, а то, что хранилище является компонентом, позволяет использовать все оптимизации, наработанные в React с его появления.


    Внутри ViewModel используется именно setState, вполне ванильно.


    Я, собственно, ничего особо против вашего проекта не имею, но вот загаживать DOM тем, чему в ней явно не место — это сильный моветон.

    Подождите, какой DOM? ViewModel ничего не рендерит в DOM, это виртуальный компонент с хранилищем для данных. Или я как-то не так вас понял?

  • Справочник по собеседованиям для тех программистов, которые их не понимают
    0

    Глас вопиющего в пустыне… Людям, которые работают с простыми, очевидными, и прекрасно контролируемым условиями в back end, никогда не понять хаоса и дикого Запада front end.

  • Как сделать React приложение быстрее при помощи совместного размещения состояний
    0
    Так что использовать, контексты или Redux?

    Ни то, ни другое. Надо использовать (бесстыжая самореклама!) Statium: https://github.com/riptano/statium. RealWorld example: https://github.com/nohuhu/react-statium-realworld-example-app


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

  • Почему я отказался от работы в AWS
    +3

    Всё верно, только не как будто. Это и есть аргументация в суде против вас.


    Я тоже не особо читал договоры и верил в человеческую порядочность, пока не привелось получить судебный иск на миллион долларов от бывшего партнёра и работодателя в своё честное, открытое физическое лицо, проживающее в социалистическом штате Канифольния. В процессе узнал много нового и интересного, например: если на вас подали иск и вы не подали прошение о защите, то истец признаётся правым автоматически, и получает всё, что запросил. Это закон. Процесс защиты долгий и сложный, документы должны быть подготовлены аккредитованными персонами — т.е. надо нанимать адвокатов. Хороший адвокат с рекоммендациями стоит $450 в час, и часов нужно много — десятки, если не сотни. Никакой "бесплатной защиты", как в кино, не положено, потому как это не уголовный иск, а гражданский. Всё за свои.


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


    Один раз пришлось отказаться, т.к. в договоре были прописаны совершенно дичайшие вещи — компания получала право в любой момент затребовать у меня все имеющиеся документы, электронные устройства, носители, и т.д., с целью контроля, а не тырю ли я их конфиденциальную информацию. И не только в течение трудоустройства, но и 3 года после увольнения. И в течение этого срока я также обязался отчитываться перед компанией, где я живу, на кого работаю, на каких условиях, чем конкретно занимаюсь, и т.д. Плюс ещё несколько интересных пунктов.


    Адвокат, честно, ох... немножечко впал в оторопь и посоветовал не соглашаться, что в общем и так было понятно. Нанимающий менеджер тоже впал в тихую оторопь после того, как я в переписке озвучил претензии к пунктам договора и привёл анализ адвоката, и начал блеять на тему: Но мы же никогда… Но это же просто рыба… Да вообще!


    Что интересно, через пару месяцев после отказа они таки вернулись и сказали, что пофиксили договор, может, чёрт возьми, нам снова?.. Но паровоз уже отчалил.


    Немаленький финтех-стартап в SF это был, дочка немаленького лидера на рынке онлайн CRM систем.

  • О столе для работы стоя, здоровье позвоночника и личной эффективности
    +1

    Дожив до возраста и доходов, позволяющих работать по 12-14 часов в день в выделенном домашнем офисе, обставленном мебелью Herman Miller, я понял, что уже вполне могу себе позволить не работать по 12-14 часов в день.


    Чего и вам желаю.

  • Зачем писать свой React Data Grid в 2019
    0

    Из альтернатив кроме ag-Grid есть ещё Bryntum Grid.

  • И еще одни странные наушники — для сна
    0

    5 лет, полёт нормальный.

  • И еще одни странные наушники — для сна
    0

    Ну беруши же.

  • Столярная мастерская своими руками: ожидания и реальность
    0
    Можно ж хобби не только для себя, а и для народа тоже :)

    Что вы, всё уже украдено до нас. :) Например: http://www.owwm.org. Я там в режиме чтения участвую, ибо добавить к этому кладезю знаний мне почти нечего.

  • Столярная мастерская своими руками: ожидания и реальность
    0

    Вы почему-то воспринимаете два этих занятия, как взаимоисключающие. Это просто хобби, сегодня одно, завтра другое. :)


    А перепродавать точно не буду, это совершенно невыгодно. Затраты по времени никогда не окупить.

  • Столярная мастерская своими руками: ожидания и реальность
    0

    Спасибо за фото и пояснения, теперь стало понятно, о чём вы говорили. Такие станки сделать действительно не проблема, при наличии рабочего пространства (пыли будет много), большого количества времени и достаточного опыта. Что-то мне подсказывает, что вы подходили к этому делу не совсем с нуля. Ну, или просто у меня руки кривые и мой опыт здесь плохо применим. :)


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


    Но тут есть другой момент: ваши задачи для этих станков сводятся к самым простым операциям с готовыми материалами. Каких-то чуть более сложных операций фанерный станок из старой циркулярки просто не потянет. Скажем, пазование без боли на нём не сделать, и что-то толще готового щита не распилить. Отрезать под углом (beveling)? Без шансов. Сделать прорези для стыков (tenoning)? Забудьте, не сойдётся. И т.д.


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


    А когда человек начинает чем-то заниматься, он ничего толком не знает. И более универсальные инструменты как раз в помощь: увидел/вычитал методику, попробуй применить и посмотри, подходит тебе или нет. Промышленный станок легко позволит это сделать и, самое главное, снять большую долю неуверенности в своих действиях. "Это инструмент плохой или у меня руки из жопы?" Если инструмент хороший, то вопрос даже не стоит. :)


    Кроме того, любые инструменты имеют погрешность. Деревянные инструменты, тем более самодельные, имеют погрешность более высокую, чем промышленные железные инструменты. В некоторых случаях, существенно более высокую. Понимать, как именно эта погрешность вылезет в конечном изделии, как это обходить, и какие запасы в размерах оставлять для доводки напильником — это непросто. Это и с опытом совсем непросто, а для начинающего столяра это добавит целое измерение фрустрации, к которому человек будет не готов. Потому что если посмотреть видосики на Йутубе, то всё это абсолютно не очевидно: там люди в основном хвастаются достижениями, но мало кто удосуживается указать на подводные грабли и подсказать, как их обойти. Всё выглядит так легко: вжик, бац-бац, и склеил. А на практике получается, что всё криво, косо, углы не сходятся, фанера нифига не плоская, ты её струбцинами, а коробка-то вышла кривая… И уже не поправишь.


    Вы же в ИТ небось работаете, про понятие learning curve знаете. И что порог входа в технологию лучше понижать, тоже. Так вот, изготовление самодельных станков, особенно как первый шаг в столярном деле, эквивалентно задиранию кривой до небес. А покупка готовых инструментов, как ни парадоксально звучит, порог входа заметно понижает.


    И, раз уж требуете фото — что ж стесняетесь приложить свои?

    По двум причинам: а) я сейчас в командировке, б) этот шкаф я уже распилил. :) Очень много места занимал, зараза. А сама пила большого интереса не представляет, т.к. покупная.