Имеет магазин получателей с Promise анти-паттерна в Reflux

Я вхожу в рефлюкс и обнимаю однонаправленный поток.

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

Вот то, о чем я думаю: Component инициализируется с состоянием загрузки. Component затем вызывает геттер на Store который возвращает Promise с success обратный вызов, который заполняет Component состояние с новыми данными и reject что населяет Component состояние с ошибкой. Если что-то обновляет StoreЯ продолжаю listenTo Store, но мой обратный звонок тот же success что используется в начальном Promise,

Это похоже на прямую реализацию Promises, но является ли это анти-паттерном в Reflux? Я понимаю, что мы не хотим изменять данные в Store, но мне трудно понять, почему Action должны быть вовлечены в простое получение.

Может кто-нибудь поправить меня?

1 ответ

Я использую действие, которое слушает api.store. Api.store - единственное место, которое обращается к объекту util/api.js, который фактически обрабатывает вызовы к серверу. Когда сервер отвечает, отправляется другое действие, которое прослушивается data.store для этих данных. Затем хранилище выдаст то, что прослушивается компонентом управления. Затем компонент управления запрашивает данные из хранилища. Это может показаться запутанным, но разделение задач делает код более понятным.

'use strict';

import React  from 'react';
import ReactDom  from 'react-dom';

import AppCtrl from './components/app.ctrl.js';
import Actions from './flux/Actions';
import ApiStore from './flux/Api.Store';

window.ReactDom = ReactDom;

Actions.apiInit();

ReactDom.render( <AppCtrl />, document.getElementById('react') );

import Reflux from 'reflux';

import Actions from './Actions';
import ApiFct from './../utils/api.js';

let ApiStoreObject = {
 newData: {
  "React version": "0.14",
  "Project": "ReFluxSuperAgent",
  "currentDateTime": new Date().toLocaleString()
 },
 listenables: Actions,
 apiInit() { ApiFct.setData(this.newData); },
 apiInitDone() { ApiFct.getData(); },
 apiSetData(data) { ApiFct.setData(data); }
}
const ApiStore = Reflux.createStore(ApiStoreObject);
export default ApiStore;

import request from 'superagent';

import Actions from '../flux/Actions';

let uri = 'http://localhost:3500';

module.exports = {
 getData() { request.get(uri + '/routes/getData').end((err, res) => { this.gotData(res.body); }); },
 gotData(data) { Actions.gotData1(data); Actions.gotData2(data); Actions.gotData3(data); },
 setData(data) { request.post('/routes/setData').send(data).end((err, res) => { Actions.apiInitDone(); }) },
};

import Reflux from 'reflux';

import Actions from './Actions';
import AddonStore from './Addon.Store';
import MixinStoreObject from './Mixin.Store';

function _GotData(data) { this.data1 = data; BasicStore.trigger('data1'); }

let BasicStoreObject = {
 init() { this.listenTo(AddonStore, this.onAddonTrigger); },
 data1: {},
 listenables: Actions,
 mixins: [MixinStoreObject],
 onGotData1: _GotData,
 onAddonTrigger() { BasicStore.trigger('data2'); },
 getData1() { return this.data1; },
 getData2() { return AddonStore.data2; },
 getData3() { return this.data3; }
}
const BasicStore = Reflux.createStore(BasicStoreObject);
export default BasicStore;

import React from 'react';

import BasicStore from './../flux/Basic.Store';

let AppCtrlSty = {
 height: '100%',
 padding: '0 10px 0 0'
}

const getState = () => {
 return {
  Data1: BasicStore.getData1(),
  Data2: BasicStore.getData2(),
  Data3: BasicStore.getData3()
 };
};

class AppCtrlRender extends React.Component {
  render() {
  let data1 = JSON.stringify(this.state.Data1, null, 2);
  let data2 = JSON.stringify(this.state.Data2, null, 2);
  let data3 = JSON.stringify(this.state.Data3, null, 2);
  return (
   <div id='AppCtrlSty' style={AppCtrlSty}>
    React 1.4 ReFlux with SuperAgent<br/><br/>
    Data1: {data1}<br/><br/>
    Data2: {data2}<br/><br/>
    Data3: {data3}<br/><br/>
   </div>
  );
 }
}

export default class AppCtrl extends AppCtrlRender {
 constructor() {
  super();
  this.state = getState();
 }

 componentDidMount = () => { this.unsubscribe = BasicStore.listen(this.storeDidChange); }
 componentWillUnmount = () => { this.unsubscribe(); }
 storeDidChange = (id) => {
  switch (id) {
   case 'data1': this.setState({Data1: BasicStore.getData1()}); break;
   case 'data2': this.setState({Data2: BasicStore.getData2()}); break;
   case 'data3': this.setState({Data3: BasicStore.getData3()}); break;
   default: this.setState(getState());
  }
 }
}

С https://github.com/calitek/ReactPatterns.

Другие вопросы по тегам