» » » Как работает mobx изнутри и сравнение его с redux

 

Как работает mobx изнутри и сравнение его с redux

Автор: admin от 22-10-2017, 11:40, посмотрело: 328

Как работает mobx изнутри и сравнение его с redux


Читая чат русскоязычного react сообщества в телеграмме (https://t.me/react_js), я вижу как с постоянной регулярностью появляются обсуждения mobx-а, сравнения с redux-ом с аргументациями про магию, сложность и "мутабельность" и у многих есть большое недопонимание что такое mobx и какие задачи он решает. И я решил написать эту статью с "разбором полетов" чтобы можно было собрать всю аргументацию в одном посте. Мы разберем как работает mobx изнутри путем реализации собственной версии mobx-а и сравним с тем как работает redux.

демку



[spoiler=Весь код в сборе][code]import React from 'react';
import { render } from 'react-dom';

let CurrentObserver;
class Cell {
constructor(val) {
this.value = val;
this.reactions = new Set();
}
get() {
if (CurrentObserver) {
this.reactions.add(CurrentObserver);
}
return this.value;
}
set(val) {
this.value = val;
for (const reaction of this.reactions) {
reaction.run();
}
}
unsubscribe(reaction) {
this.reactions.delete(reaction);
}
}

class ComputedCell extends Cell {
constructor(computedFn, reactionFn) {
super();
this.computedFn = computedFn;
this.reactionFn = reactionFn;
this.value = this.track();
}

track(){
const prevObserver = CurrentObserver;
CurrentObserver = this;
const newValue = this.computedFn();
CurrentObserver = prevObserver;
return newValue;
}

run() {
const newValue = this.track();
if (newValue !== this.value) {
this.value = newValue;
CurrentObserver = null;
this.reactionFn();
}

}
}

function observable(target, key) {
return {
get() {
if (!this.__observables) this.__observables = {};
let observable = this.__observables[key];
if (!observable) observable = this.__observables[key] = new Cell();
return observable.get();
},
set(val) {
if (!this.__observables) this.__observables = {};
let observable = this.__observables[key];
if (!observable) observable = this.__observables[key] = new Cell();
observable.set(val);
}
}
}

function observer(Component) {
const oldRender = Component.prototype.render;
Component.prototype.render = function(){
if (!this._reaction) this._reaction = new ComputedCell(oldRender.bind(this), ()=>this.forceUpdate());
return this._reaction.get();
}
}

class Timer {
@observable count;
constructor(text) {
this.count = 0;
}
}

const AppState = new Timer();

@observer
class App extends React.Component {
onclick=()=>{
this.props.timer.count++
}
render(){
console.log('render');
const {timer} = this.props;
return (

{timer.count}


)
}
}

render(Ден Абрамов и что более важно — не происходит создание n-объектов в функции mapStateToProps. Во вторых — когда нам нужно обновить какие-то данные мы можем просто написать comment.text = 'new text' и нам не придется выполнять еще кучу работы по обновлению родительских объектов состояния, и что важно — не будет нагрузки на сборщик мусора из-за постоянного пересоздания объектов. Ну и главное — мы можем моделировать состояния с помощью объектов которые ссылаются друг на друга и сможем удобно работать с состоянием без необходимости хранить вместо объекта айдишник а потом вытаскивать каждый раз из хеша AppState.folders[AppState.projects[AppState.tasks[comment.taskId].projectId].folderId].name вместо простого обращения по ссылке comment.task.project.folder.name



Вывод



Если вы разобрались в этих примерах — то поздравляю — вы теперь понимаете как работает изнутри "магия" mobx. И если не брать во внимание наличие в mobx @computed декоратора который делает умную мемоизацию и не будет пересчитывать значение несколько раз в процессе инвалидации (эта оптимизация достойна отдельной статьи) и разных хелперов то мы только что реализовали весь механизм обсерверов mobx-а и выяснили что их работа проста и предсказуема и разобрались в преимуществах подхода с обсерверами против иммутабельного подхода для реализации задачи точечного обновления компонентов react-а.



Источник: Хабрахабр

Категория: Операционные системы » Android

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

Добавление комментария

Имя:*
E-Mail:
Комментарий:
Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
Введите два слова, показанных на изображении: *