Comments 51
Материал подробный и для многих полезный, но меня пугают приложения типа todo list или голосование с размером кода в 400-500кб ради нескольких экранов и состояний.
Если ограничится только таким функционалом, как todo list — то использование React/Redux — это overkill. Однако, на таких небольших примерах показывается архитектура масштабируемых и поддерживаемых приложений.
Только не говорите, что таким образом в Mail.ru строят клиентскую часть приложения на react/redux.
Где человеческое разделение на container/presenter?
Где ES2015/ES7 через babel? Куда удобнее использовать array/object spread, вместо нагораживания immutable.
Где stateless function components, которые в скором времени будут выступать в роли де-факто presenter'ов?
Про валидацию props слышали?

/me подумывает о серии статей по bleeding-edge development with redux.

Ток написал об этом, а вы опередили, — жаль ребят из mail'а.

Сотрудники mail.ru просто любят экспериментировать с чем-то новым, и они переводят статьи для публики — замечу все это они делают в свободное время.
А это просто перевод, он не призывает к действию и не отражает процессы проходимые в mail.ru )

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


P.S. Можно без тестов, да и детализация такая не нужна.

Это перевод статьи http://teropa.info/blog/2015/09/10/full-stack-redux-tutorial.html от 10 сентября 2015.

Напишите, потому что я только месяц назад прочитал эту статью и считаю/считал что она шикарна и прямо труъ труъ. А то остальные туториалы ещё хуже.

На счет immutable не согласен
Один только immutable.Record дает очень многое
Не надо забывать, что
class Car {
constructor(manufacturer, model, speed) {
this.model = model;
this.manufacturer = manufacturer;
this.speed = speed;
}

getTitle = () => `${this.manufacturer} ${this.model} ${this.speed}км/ч`;
}

const myCar = new Car('Lada', '2101', 100);
console.log(myCar.getTitle()); // Lada 2101 100км/ч

const modifiedCar = {...myCar};
console.log(modifiedCar.getTitle()); // undefined

console.log(myCar instanceof Car)// true
console.log(modifiedCar instanceof Car)// false
а вы вообще понимаете, что spread и immutable не всегда дают такой же эффект?

E.g.: immutable не создает новый объект, если данные реально не были изменены, spread — создаст.

Можно же проверить, изменились ли данные и вернуть новый объект через spread

ага, и еще потом запилить оптимизацию для хранения данных и в итоге получим immutablejs
В более сложном чем счетчик reducer, запросто могут быть объекты. Например, что-то типа ORM для более удобного работы с объектами. В реальном приложении state далеко не примитивны.

Разве immutable-js может работать с прототипированными объектами? Есть пример? Но если даже так, я в реальных приложениях store поддерживаю примитивным, ведь это как хранилище данных.

Я не утверждаю, что immutable панацея, нужно смотреть на требования. В текущем проекте, например, immutablejs не используем.

p.s.: хранилище данных может быть сложным, если, например, нужно повторить «структуру БД», а если еще и несколько схем, то все усложнится в разы. это все application specific и выбирать инструмент нужно по требованиям.

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

Когда лучше подходит immutable-js? Думал вы утверждаете, что immutable-js для сложных store, но и вы его в такой ситуации не используете. Хм.

в данный момент нам не нужна оптимизация, нужно удобство, которое мы получили через redux-orm + reselect.

А это проще (и другие критерии), чем среагировать на нужный action.type соответствующего модуля для синхронизации? То что состояния для разных компонентов должны быть синхронизированы есть частный случай. Были попытки автоматизировать синхронизацию, но практика доказала, что луче всеми силами отставить простоту без магии.

что именно? redux-orm? У нас связи между моделями + reselect иногда не тривиальный был, в итоге поняли, что практически сделали «то же самое, но свое». orm мы только для локального кэша объектов из БД используем, для других частей, простые reducer, без orm.
да даже пусть у вас будет просто объект, с 10 полями. Вы будете все их проверять и потом делать spread, если было реальное изменение?

{ name: 'aaa', age: 10, email: 'spam@spam.it', .....}
прилетает запрос на выставление age в 10 или даже на age + email. Данные не поменялись, но запрос прилетел. Можно сделать spread:

{ ...state, ...action.updates}

и получим новый объект (данные не поменялись на самом деле, прилетел запрос на изменение такой: { age: 10, email: 'spam@spam.it'). immutable вернет тот же объект.

В 99% случаях не буду проверять. Оптимальность изменения store от архитектуры приложения зависит.

/me подумывает о серии статей по bleeding-edge development with redux.

"Уж полночь близится, а Германа всё нет"

Закидают помидорами, но:


  • React.createClass и используете babel ?
  • Mixin'ы — если ваше приложение не должно работать на React.Native то зачем ?
  • JSDom — зачем ?
  • bindActionCreators ?
  • Почему не показали принципы умных и глупых компонентов ?
  • combineReducers?
  • 0.14 React?
  • Universal app ?
  • Актуальность данной работы ?

Я похоже очень плохо понимаю redux, и мне кажется я очень неправ как и этот парень со своими уроками, вон выше то статья, — как статья. Все понятно, — доходчиво то как.


Мы совсем не учимся и не смотрим/читаем что нам дают.
Прости нас Даниил, прости пожалуйста.

А как читать egghead.io? Там только ведь затянутые видео.


PS: Открываю по вашей ссылке последнее видео, там прямо на скрине {combineReducers}. Вы сами-то смотрели их? В чем смысл спрашивать про "combineReducers?" тогда?

image


Надеюсь не сильно ярко ?


Если что ссылка ведет на github.


PS: Мои вопросительные знаки больше означают (с чуточкой сарказма) так — "ГДЕ %functionName%?".

Хорошая статья — показывающая как не надо делать фронтенд.

«приложение для «живых» голосований» в тысячи строк кода? спасибо не надо.
такое пилится в несколько десятков строк кода на чистом JS
без всяких реактов и редаксов и прочей мути.
expect(winner).to.be.ok;

Никогда не понимал, откуда появилася дурацкая идея писать через точку это. Да еще и нестрого (можно пропустить to и be) Чем оно лучше toBeOk()? Тем, что подсвечивается как ошибка и не автодополняется в IDE? Тем, что в команде кто-то будет писать .to.equal, кто-то .to.be.equal? Дополнительная нагрузка на код-ревью. Ради чего? Просто чтоб понты поколотить?

Непоследовательность даже в официальной документации:
expect(Chai).to.be.an.instanceof(Tea);
expect([ 1, 2, 3 ]).to.be.instanceof(Array);

То необходимо ставить an или нет?

Надеюсь, эта дурацкая мода быстро пройдет.
Полагаю дело в том, что множественному числу, под которым подразумевается Array артикль не ставится… И нет, я не считаю что есть какой-то смысл в этих заморочках… Если уж на то пошло, то о конкретном экземпляре имеет смысл говорить вообще The, если не ошибаюсь))))

Прелесть в том, что можно писать expect(Chai).instanceof(Tea); или expect(winner).ok;


Всякие .to.be.an — просто сахар для граммар-наци

Этот сахар работает через геттеры. Когда такая конструкция реализуется — её необходимость должна быть очень весомо аргументирована. Поддержу TheShock в том что это было сделано во славу Сатане.
Сахар нужен чтоб потом со спеки можно было чуть ли не текстовое описание сгенерировать.
Я слышал такое, но пока выглядело как миф. Можно увидеть пример, когда спека с тестами похожи настолько, чтобы можно было так просто генерировать их?
Есть еще такой момент, что это все было особо популярно для UI спецификаций, мол, кликни туда, увидь это, напечатай то. И вот их как раз генерировать вполне можно. Для суровых юнит тестов это несколько меньше подходит, вряд ли кто-то потом с распечатанной спекой будет смотреть на класс и думать, работает ли он как написано )

Хороший материал, но многовато за один раз. Лучше бы разбить на 2-3 статьи.

А самому читать за несколько подходов никак? Тем более что в начале есть оглавление.

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

Вопрос по одному из принципов redux архитектуры — по требованию хранить все состояние программы в одном объекте. Допустим, есть большая модульная программа, которая имеет несколько сборок с различной комбинацией этих модулей. Как достичь независимости модулей если у них всех один общий state? В классическом ООП модуль полностью изолирует и свой state и свое поведение за счет инкапсуляции классов, а связь между модулями устанавливается специальным кодом, вне модулей.
Вообще сложилось мнение, что redux подходит только для небольших проектов, со своей спецификой. Например, где данные сильно не привязаны к способам их изменения.

В большой модульной программе с различными сборками меньше всего проблем возникает как раз со State модулей:
1) Никто не мешает модулю иметь свой state, он может быть отдельно написанным приложением со своим API, и не обязательно написан с Redux
2) Проблема в общем то надуманна, т.к. если программист написал два модуля и их state пересекаются, то Redux не виноват. Так можно постараться написать с любым стеком. У модуля своя зона ответственности в state, он должен зависеть только от нее, а для взаимодействия с общим состоянием есть Actions, которые изолированы от state
В зависимости от бандла подключаем разные reducer'ы при инициализации стора. В итоге у нас будут в наличии либо отсутствовать некоторые поддеревья общего дерева состояния.
6-й NodeJS поддерживает декларативно 95% ES6, можно обойтись без Babel.
У вас ссылка битая в статье
https://facebook.github.io/immutable-js/docs/#/Listf

(f лишняя на конце)
Only those users with full accounts are able to leave comments. Log in, please.