Pull to refresh
0
0
Ястребков Артем @Nerlin

Full-Stack Developer

Send message
Тоже очень расстроился, когда увидел сколько новое Context API генерирует мусора в дереве. А если наложить на это styled components с темами…

Поделитесь опытом, как Вы с этим боретесь?
Если есть множество чистых функций, их можно вычислять в любом порядке. Опять же, это не может повлиять на финальный результат.


Думаю, вот этот момент нуждается в пояснении, потому что банальный пример ниже показывает нам обратное (python):

def add2(value):
    return value + 2
    

def mul2(value):
    return value * 2
    
print add2(mul2(2))
print mul2(add2(2))


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

Разумеется это не всегда так, иногда разработчик уже знает что делает класс и хочет разобраться в конкретном методе, но тогда, скорее всего, он уже знает как и что ему конкретно искать.
До абсурда доводите Вы, приводя такие примеры. Более верной аналогией в Вашем же примере было бы: «Хотите в туалет — не срите там же, где работаете». Почему в квартире есть отдельные места для каждого занятия — зал, кухня, спальня, туалет, а не одна комната для всего? Возможно, Вам было бы удобно одновременно стоять в душе и готовить яичницу, но это не значит, что это будет действительно эффективно.

Ближе к делу. Кода не увеличится в разы, добавится одна лишь функция, занимающая строки две, по сравнению с тем же кодом, который расположен будет у Вас в reducer с нарушением SRP, зато reducer при этом останется чистым. Изменится лишь вызов. К тому же, Вы рассматриваете лишь тот случай, когда сохранять одновременно нужно и в store, и в storage, а если нужно что-то сохранить лишь в store с тем же action или если нужно применить sessionStorage или вообще что-то иное почему-то нет. Может конечно у Вас весь store всегда хранится в localStorage, я не знаю, но смысла в этом я не вижу никакого, зачем эта зависимость в принципе нужна в reducer'е? Человек, не знакомый сразу с Вашим проектом, должен будет изучить эту особенность реализации и знать, что что-то изменяя в state, он вносит изменения и в localStorage, лучше эту особенность выделить явно в отдельную функцию.
Потому что это нарушает SRP.

Почему в таком случае не выделить функцию, которая будет запускать этот необходимый код, а затем вызывать dispatch и изменять состояние приложения? Зачем мешать логику изменения текущего состояния с кешированием или другими процессами?
У нас в институте все так и работало — всю группу разбивали по 2-3 человека на практических и лабораторных занятиях. Люди учились работать вместе над одной проблемой, анализировать задачу и оценивать код, делясь почему так надо или не надо делать. Более опытный студент помогал развиваться отстающим, если им конечно было это интересно.
Прочитал и вспомнил времена, когда в киосках продавали всякие бустеры Magic the Gathering и фишки и вспомнил как в детстве расстроился, когда однажды пришел в такой киоск и не увидел любимой продукции. Давно уже отошел от этого, но проходя мимо и увидев бы это сейчас, я бы лично не удержался и купил. Конечно, для настольных игр, наверное, более актуально иметь магазин-игровой клуб, в котором можно не только купить эту игру, но и показать как в нее играть, но и этот эксперимент интересен. Жду еще одну статью, в которой напишите, что в итоге получилось.
В случае наличия сзади сервера на Node.JS, Вы можете отдавать favicon и критический css сразу, а остальное подгружать постепенно через метод renderToNodeStream. Никакого двойного трафика и двойных походов к API не нужно, initial state для Вашего store Вы можете загрузить на сервере, отрендерить контент, а затем сохранить store внутри какого-нибудь window.__initialState__, после чего уже забрать это состояние на клиенте.
Эту логику вы должны реализовать на сервере, прежде чем вызывать метод renderToString или renderToNodeStream — загружаете нужные данные согласно текущему url, формируете из них store и уже все это готовое отдаете в компонент Provider, который затем рендерите через renderToString или renderToNodeStream.
Доля рынка таких пользователей настолько мала, что ими сейчас можно пренебречь. Рынок диктует потребитель и пока таких, как Вы, не станет большинство, то смысла изворачиваться разработчикам и нет. Важнее поставлять работающий функционал в более краткие сроки, чем это делают конкуренты, а для этого разработчик будет использовать то, что ему более удобно, будь то React, jQuery или чистый JS с биндингом напрямую к DOM.

Разработчики Instagram решили, что реализуя приложение как SPA, им будет проще его сопровождать, а может им просто нравился тот инструментарий, получать удовольствие от работы тоже важно. Эти простые истины переписать не так легко.
Потому что человек не способен предугадать развитие функциональных требований и стоит появиться случаю, когда понадобится более сложное поведение, придется бежать приделывать костыли и палки. Да, не всегда это так, бесспорно, но только ради того, чтобы не включать JS, я не готов строить свою систему с надеждой, что мне он никогда и не понадобится. Лично мне будет проще сразу взять тот же React и быть готовым к любой необходимой динамике в интерфейсе или любым взаимодействиям.
Может неправильно выразился, попробую переформулировать. Если есть намек на какую-то динамику на странице, почему бы и не сделать SPA, тем более в век адекватного пререндеринга или вообще возможности создавать изоморфное приложение? Из минусов вижу только Вами представленный случай с отключенным JS, но лично я не знаю насколько этот случай охватывает рынок, чтобы о нем задумываться.

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

А зачем? Этот момент мне лично не понятен.
Из ответа не очень стало понятно зачем все-таки mobx-state-tree, если мы можем напрямую использовать mobx, описывая состояние приложения через ES6-классы. И как непосредственно кроме отладки или логгинга используется onSnapshot? Или это и есть место для всякого подобного middleware кода?

PS обратите внимание, в слове «MobX» третья буква — b а не d. ModX — это совсем другой проект.

Увидел опечатку уже после отправки, когда нельзя было редактировать пост. А вроде бы просто налил себе чай, отвлекся буквально на минуту, эх, Хабрахабр. Имел дело и с этим другим проектом, видимо, опечатался.
Спасибо за доклад, было довольно увлекательно, но остались некие вопросы. Вы говорите, что mobx-state-tree работает с данными аналогично тому, как react работает с компонентами, но я не совсем понял сферу его применения. Если в компонентах мы не используем getSnapshot и onSnapshot, а используем observable из modx, то mobx-state-tree нужен лишь для time traveling?

Еще показалось интересным, что в начале доклада Вы показываете кусочек кода с ручной подпиской на изменения через state.on('change'), а в конце доклада мы видим весьма похожую функцию onSnapshot, которая уже такой плохой не считается. Поясните и ее предназначение, пожалуйста.

Также как-то немного выпало из доклада, вот этот хелпер types — это часть modx?
Простите, но в чем тогда принципиальная разница между SPA и не SPA, если все равно прикручиваем AJAX для асинхронного изменения контента, только кашу на сервере и клиенте наводить. Или у Вас каждый день встречаются случаи, когда у пользователя отключен JS?
Не виноваты. Но, позиционируя себя как простой редактор, а не IDE, можно было бы за поддержку попросить и поменьше.
Использовал Sublime Text 3 beta, потом увидел VS Code. Поставил, понравился, нет надоедающего окна-попрошайки, есть все нужные плагины. Я бы купил Sublime Text, если бы разработчики не просили таких боснословных денег, за которые и вполне себе WebStorm покупается.
Опять же, чтобы реализовать обертки, в начале нужно разобраться с этим гигантским классом. Если Вы работаете в проекте один, то таких проблем может быть Вы и не встретите, если конечно не забросите проект на год, а потом не попробуете к нему вернуться. Но опыт подсказывает, что, например, новые сотрудники разбираются с огромными участками кода намного дольше, чем с маленькими разбитыми блоками как у автора, пусть даже их и несколько.

Плюс ко всему, выше можете почитать рассуждения по поводу оберток и к чему приводит их повсеместное использование.
Причем здесь фичи? Выглядит как будто Вы отвечаете сам себе. Речь идет о типизации и возможности описывать внешний вид класса или метода, что, как я считаю, и является основным смыслом, за которым стоит использовать TypeScript в своих проектах. Все фичи аля spread, const, let и прочее — это хорошо, но речь то не о них, они уже введены повсеместно, и в ES6, и в TypeScript, и в CoffeeScript.
Есть и Flow, и уверен кучу велосипедов, это нынче в мире JS популярно, только причем тут CoffeeScript? Он с описанием классов и сигнатур никак не помогает, просто позволяет писать код на JS, похожий на какой-то функциональный язык, с кучей символов так любимых фанатами Haskell. Выглядит это максимум лаконичнее, но никак в сопровождении и понимании самого кода не помогает, а местами даже и вредит.
1

Information

Rating
Does not participate
Location
Орел, Орловская обл., Россия
Date of birth
Registered
Activity