ݺߣ

ݺߣShare a Scribd company logo
От Backbone к React
Зачем и как
Игорь Лобанов
Kaiten.io
● Возраст: ~2 года
● Первая продакшн версия появилась через 3 месяца
● Frontend: Backbone (Marionette), React, Redux, ~50KSLOC
● Backend: Node (Express), PostgreSQL (+хранимые епроцедуры на plv8),
RabbitMQ, Redis
Backbone -> React: зачем?
FrontDays #2. Игорь Лобанов, Миграция Backbone (Marionette) -> React + Redux
Backbone -> React: зачем?
Цели:
● Увеличить скорость разработки
● Сократить технический долг
● Перейти на использование готовых UI
компонентов
React глазами разработчика на Backbone
const MyView = Marionette.ItemView.extend({
modelEvents: {
'change': 'render'
}
});
const MyView = Marionette.ItemView.extend({
modelEvents: {
'change:active': 'onChangeActive',
'change:checked': 'onChangeChecked'
},
onChangeAction: function() {
this.$el.toggleClass('active', this.model.get('active'));
},
onChangeChecked: function() {
this.$('input[type="checkbox"]').prop({
checked: this.model.get('checked')
});
}
});
Backbone Marionette глазами React разработчика
Как было и как будет
Было Будет
Сейчас
Грабли
Не наступили:
● Не стали использовать иерархический стейт
● Не стали использовать старые стили, а перешли на inline styles
Наступили:
● Radium и React Motion
● Иммутабельность
Иммутабельность
Сколько здесь проблем с иммутабельностью?
const shallowCompare = require('react-addons-shallow-compare');
class ToDoListItem extends React.Component {
shouldComponentUpdate (nextProps, nextState) {
return shallowCompare(this, nextProps, nextState);
}
}
class ToDoList extends React.Component {
render () {
return (
<ToDoListItem
style={{marginTop: 8}}
onSave={this.onClick.bind(this)}
onRemove={() => this.onRemove()}
/>
);
}
}
Иммутабельность
Правильный ответ: 3
1. {marginTop: 8} - всегда новый объект, использовать const для стилей
2. this.onSave.bind(this) !== this.onSave.bind(this), bind можно делать в
конструкторе
3. () => this.onRemove() - всегда новая функция
Результаты
● Вероятность устранения бага за 5 дней: 73% -> 83%
● За 1 день 27% -> 44%
Результаты
Вероятность реализации новой фичи за 10 рабочих дней: 67% -> 79%
Результаты
Результаты
● Снизился порог входа для разработки frontend (человек, который
занимался только бекендом начал делать фичи полностью)
● Подключили Material UI
● Избавились от части архитектурных проблем
● Скорость работы переписанной функциональности существенно не
изменилась
● Количество кода отвечающего за переписанную часть осталось
примерно тем же
Спасибо. Вопросы?

More Related Content

FrontDays #2. Игорь Лобанов, Миграция Backbone (Marionette) -> React + Redux

  • 1. От Backbone к React Зачем и как Игорь Лобанов
  • 2. Kaiten.io ● Возраст: ~2 года ● Первая продакшн версия появилась через 3 месяца ● Frontend: Backbone (Marionette), React, Redux, ~50KSLOC ● Backend: Node (Express), PostgreSQL (+хранимые епроцедуры на plv8), RabbitMQ, Redis
  • 3. Backbone -> React: зачем?
  • 5. Backbone -> React: зачем? Цели: ● Увеличить скорость разработки ● Сократить технический долг ● Перейти на использование готовых UI компонентов
  • 6. React глазами разработчика на Backbone const MyView = Marionette.ItemView.extend({ modelEvents: { 'change': 'render' } }); const MyView = Marionette.ItemView.extend({ modelEvents: { 'change:active': 'onChangeActive', 'change:checked': 'onChangeChecked' }, onChangeAction: function() { this.$el.toggleClass('active', this.model.get('active')); }, onChangeChecked: function() { this.$('input[type="checkbox"]').prop({ checked: this.model.get('checked') }); } });
  • 7. Backbone Marionette глазами React разработчика
  • 8. Как было и как будет Было Будет
  • 10. Грабли Не наступили: ● Не стали использовать иерархический стейт ● Не стали использовать старые стили, а перешли на inline styles Наступили: ● Radium и React Motion ● Иммутабельность
  • 11. Иммутабельность Сколько здесь проблем с иммутабельностью? const shallowCompare = require('react-addons-shallow-compare'); class ToDoListItem extends React.Component { shouldComponentUpdate (nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } } class ToDoList extends React.Component { render () { return ( <ToDoListItem style={{marginTop: 8}} onSave={this.onClick.bind(this)} onRemove={() => this.onRemove()} /> ); } }
  • 12. Иммутабельность Правильный ответ: 3 1. {marginTop: 8} - всегда новый объект, использовать const для стилей 2. this.onSave.bind(this) !== this.onSave.bind(this), bind можно делать в конструкторе 3. () => this.onRemove() - всегда новая функция
  • 13. Результаты ● Вероятность устранения бага за 5 дней: 73% -> 83% ● За 1 день 27% -> 44%
  • 14. Результаты Вероятность реализации новой фичи за 10 рабочих дней: 67% -> 79%
  • 16. Результаты ● Снизился порог входа для разработки frontend (человек, который занимался только бекендом начал делать фичи полностью) ● Подключили Material UI ● Избавились от части архитектурных проблем ● Скорость работы переписанной функциональности существенно не изменилась ● Количество кода отвечающего за переписанную часть осталось примерно тем же