拥有Promise的Store getters在Reflux中具有反模式

时间:2015-10-27 23:51:39

标签: reactjs refluxjs

我正在逆流而且正在接受单向流动。

那就是说,我正在努力解决组件必须触发动作只是为了从商店获取数据的想法。这是我见过的很多例子,但在请求数据而不是被告知有新数据时似乎很奇怪。

以下是我的想法: Component初始化为加载状态。 然后,Component会在Store上调用一个getter,它会返回一个Promise,其中success回调会使用新数据填充Component状态,并reject 1}}填充Component状态并显示错误。如果某些内容更新Store,我会继续listenTo Store,但我的回调与初始success中使用的Promise相同。

这似乎是Promises的直接实现,但它是Reflux中的反模式吗?我知道我们不想改变Store中的数据,但我很难理解为什么Action需要参与简单的获取。

有人能让我直截了当吗?

1 个答案:

答案 0 :(得分: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