Запутался в архитектуре React Flux

У меня есть собственное мнение о том, как использовать React, и я создаю свой собственный фреймворк, вдохновленный Омом. Я реализую что-то похожее на архитектуру Flux, с хранилищами, которые могут обновляться при некоторых событиях.

Чего я не уверен, так это почему в архитектуре Flux нам нужны хранилища зависимостей?

Хранилища не должны быть автономными держателями данных для заданного ограниченного контекста, как мы делаем с архитектурами CQRS?

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

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


person Sebastien Lorber    schedule 10.08.2014    source источник
comment
Где вы остановились на этом?   -  person bentayloruk    schedule 10.06.2015
comment
@bentayloruk проверьте github.com/stample/atom-react . Также Дэн Абрамов экспериментирует с компонуемостью хранилища вместо зависимости (я как-то тоже так делаю). См. gist.github.com/gaearon/d77ca812015c0356654f.   -  person Sebastien Lorber    schedule 10.06.2015


Ответы (2)


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

По сути, хранилища данных — это компоненты CQRS, и я стараюсь избегать того, чтобы два хранилища данных в конечном итоге содержали одинаковые данные. Если мне нужно каким-то образом преобразовать данные, которые нужны только некоторым компонентам, я разбиваю их на «агрегированное» хранилище данных. Наивная реализация:

var carsStore = Reflux.createStore({
    init: function() {
        this.listenTo(Actions.updateCars, this.updateCallback);
    },
    updateCallback: function() {
        $.ajax('/api/cars', {}).done(function(data) {
            this.trigger(data.cars);
        }.bind(this));
    }
});

Мы можем создать еще одно хранилище данных, которое агрегирует данные, прослушивая carsStore:

var modelsStore = Reflux.createStore({
    init: function() {
        this.listenTo(carsStore, this.carsCallback);
    },
    carsCallback: function(cars) { // passed on from carsStore trigger
        this.trigger(this.getModels(cars)); // pass on the models
    }
    getModels: function(cars) {
        return _.unique(_.map(cars, function(car) { return car.model; }));
    }
});

Таким образом, ваши компоненты представления React могут использовать один для получения автомобилей, а другой — для получения моделей, которые собираются из файла carStore.

Если магазину необходимо дождаться завершения двух параллельных потоков данных, мы предоставляем Reflux.all для объединения действий и хранилищ. Это полезно, например. если вы ожидаете загрузки данных из разных ресурсов REST.

var carsAndPartsAreLoaded = Reflux.all(carStore, partsStore);

// you may now listen to carsAndPartsAreLoaded 
// from your data stores and components

Надеюсь, это имеет смысл для вас.

person Spoike    schedule 11.08.2014
comment
Мы постараемся упростить обработку CRUD-команд в рефлюксе по сравнению с автономным локальным хранилищем и адаптером для веб-API. Скорее всего, это станет расширением, поскольку ядро ​​refluxjs может использоваться на стороне сервера (в NodeJS). - person Spoike; 11.08.2014
comment
Я думаю, что дублирование данных на самом деле является решением, позволяющим не иметь никакой зависимости между хранилищами Flux и, таким образом, не иметь дело с синхронизацией хранилищ. Что ты думаешь об этом? msdn.microsoft.com/en-us/library/bb245672.aspx - person Sebastien Lorber; 12.08.2014
comment
@SebastienLorber Почему вы считаете необходимым не иметь зависимости между магазинами? Одна из проблем, которую Facebook пытался устранить с помощью Flux, заключалась в том, чтобы избежать работы с транзитивными данными в компонентах, которые были основным источником ошибок (согласно видео). Синхронизация данных в веб-приложении решается автоматически в Flux путем подачи сигналов или передачи данных в виде предсказуемого однонаправленного потока. - person Spoike; 12.08.2014
comment
Извините, но я не понимаю, что вы имеете в виду под transitive data between components и на какую часть видео вы ссылаетесь. Я думаю, что создание автономных хранилищ также очень предсказуемо, поскольку события хранилища становятся источником правды и лучше масштабируются на большой кодовой базе, так как при разработке одного компонента вам не нужно понимать, как работают другие компоненты, а только бизнес-события, которые могут быть уволенным. Скажите, что в вашем дизайне Flux никогда не бывает так, что вы хотите провести рефакторинг одного магазина, а в качестве побочного эффекта вам приходится рефакторить другой магазин? - person Sebastien Lorber; 12.08.2014
comment
@SebastienLorber Ой. Я имел в виду производные данные, они обсуждают это с вариантом использования в видео около 14:00-17:00 мин. Я думаю, что мы на одной волне в том, что события в магазине становятся источником правды. В рефлюксе вы подключаете компоненты (как хранилища, так и реагирующие компоненты), подписываясь на события в действиях или других хранилищах. Они будут получать данные о событиях из хранилища, скорее зная, что оно делает внутри, и вы не должны знать точный интерфейс магазинов, которые вы слушаете. - person Spoike; 12.08.2014

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

Недавно Дэн Абрамов создал инфраструктуру (Redux), которая подчеркивает возможность компоновки хранилищ Flux без необходимости какой-либо зависимости от хранилища или waitFor, и я разделяю большинство его идей

person Sebastien Lorber    schedule 15.07.2015