我正在尝试在Flux-React中设置最基本的应用程序.它的唯一目标是触发一个Action,它通过Dispatcher发送到已经向Dispatcher注册的Store.将商店记录payload到控制台.
除了Store之外的所有东西都运行良好,但是一旦它命中AppDispatcher.register,Flux就会抛出以下错误:
Uncaught TypeError: Cannot set property 'ID_1' of undefined
Run Code Online (Sandbox Code Playgroud)
这是导致错误的文件的代码,但我已经把整个项目放在https://github.com/bengrunfeld/react-flux-dispatcher-error,你可以在src/js中找到有问题的文件/stores/AppStores.js
var AppDispatcher = require('../dispatcher/AppDispatcher');
var EventEmitter = require('events').EventEmitter;
var AppConstants = require('../constants/AppConstants');
var assign = require('object-assign');
var CHANGE_EVENT = 'change';
var AppStore = assign({}, EventEmitter.prototype, {
emitChange: function() {
this.emit(CHANGE_EVENT);
}
});
AppDispatcher.register(function(payload){
console.log(payload);
return true;
})
module.exports = AppStore;
Run Code Online (Sandbox Code Playgroud) 如何使用reactjs.net在asp.net中创建flux通信架构?
我会有几个文件.Jsx,我将如何通过服务器成为所有rendenizador?
在这个例子中=> Link,它使用asp.net创建,但不使用服务器渲染
我开发的应用程序最初是使用Flux构建的.
但是,随着时间的推移,应用程序变得更难维护.有很多行动.通常只在一个地方(商店)收听一个动作.
操作可以不在一个地方编写所有事件处理程序代码.所以不是这样的:
store.handleMyAction('ha')
another.handleMyAction('ha')
yetAnotherStore.handleMyAction('ha')
Run Code Online (Sandbox Code Playgroud)
我可以写:
actions.myAction('ha')
Run Code Online (Sandbox Code Playgroud)
但我从不以这种方式使用行动.我几乎可以肯定,这不是我申请的问题.
每次我打电话给一个动作,我都可以打电话store.onSmthHappen而不是action.smthHappen.
当然,在一些地方处理一个动作时也有例外.但是当发生这种情况时,感觉就像出了问题.
如果不是调用动作而是直接从商店调用方法呢?我的申请会不会那么灵活?没有!仅发生重命名(极少数例外).但是要付出什么代价!通过所有这些操作来理解应用程序中发生的事情变得更加困难.每次跟踪复杂动作的处理时,我都必须在商店中找到它们的处理方式.然后在这些商店中我应该找到调用另一个动作的逻辑.等等.
现在我来解决我的问题:
有控制器直接从商店调用方法.所有的逻辑如何处理行动是在商店.还存储对WebAPI的调用(通常是与一个WebAPI相关的一个商店).如果事件应该在几个商店中处理(通常是顺序的),那么控制器通过编排从商店返回的承诺来处理这个事件.私有方法中的一些序列(常用).控制器的方法可以将它们用作处理的简单部分.所以我永远不会复制代码.
控制器方法不返回任何内容(单向流).
实际上,控制器不包含如何处理数据的逻辑.它只是指向哪里,以什么顺序.
您几乎可以看到商店中数据处理的完整图片.商店里没有关于如何与其他商店互动的逻辑(通过它就像一个多对多的关系,但只是通过行动).现在,商店是一个高度凝聚力的模块,只负责域模型(集合)的逻辑.
主要(在我看来)助焊剂的优势仍然存在.
因此,有商店,这是唯一真正的数据来源.组件可以订阅商店.组件调用与以前相同的方法,但不是actions使用controller.与React的交互根本没有改变.
此外,事件处理变得非常明显.现在我可以看一下控制器中的处理程序,一切都变得清晰,调试起来要容易得多.
问题是:
为什么行动创造了变化?他错过了哪些优势?
我正在研究一个flux应用程序,我正在考虑采用immutable.js来维护状态.我看到react提供了自己的帮助器来更新不可变对象(http://facebook.github.io/react/docs/update.html),但是无法告诉它与immutable自己的setIn和updateIn方法有什么不同(也就是说,我已经可以将对象与===进行比较,如果它们随setIn变化.是否有理由将react helper与immutable.js一起使用?它只是语法糖吗?
TL; DR是:
var map = Immutable.fromJS({bar: 'baz'});
map2 = React.addons.update(map, {
bar: {$set: 'foo'}
});
Run Code Online (Sandbox Code Playgroud)
不同于
var map = Immutable.fromJS({bar: 'baz'});
map2 = map.set('bar', 'foo');
Run Code Online (Sandbox Code Playgroud) 存储应该处理由操作触发的事件并将更改发送到侦听视图控制器.
他们也可以触发操作,例如在请求的回调中或直接在商店的注册回调中.
例如:
AppDispatcher.register(function(payload) {
switch(payload.action.actionType) {
case Constants.PAGE_CHANGED:
ActionCreator.fetchNewData();
break;
case Constants.FETCH_DATA:
// save data
Store.emitChange();
break;
}
});
Run Code Online (Sandbox Code Playgroud)
Flux架构中的代码是否"正确"?
谢谢 !
======基于评论的更新:
这不是"我需要这样做.我该怎么做?"的问题,而是"这应该是一种做事方式".我猜答案是......你的选择.
感谢您在评论中添加了一些有用的链接.
我对事情的理解如下:
在Flux架构中,视图应该是唯一触发操作的视图.将异步请求放入您的操作创建者中,并且回调应该启动新操作.
如果不遵循Flux步骤,商店也可以处理异步请求,但要确保回调不直接处理数据,而是触发另一个操作.请参阅Bill Fisher对此的回答.
无论如何,正如Ben Alpert的回答所说,您可以为用户操作创建多个操作(例如:REQUEST_START,REQUEST_SUCCESS,REQUEST_ERROR),这样您就可以挂钩到请求的不同阶段.
欢迎任何有关此事的更新.
在flux webchat示例应用程序和README图中,似乎操作创建者应该从服务器检索数据.

我看到的问题是,如果数据已经存储在商店中,则可能不需要提取.商店是唯一知道的商店,因此需要实际调度行动.
我认为最好在可能的情况下获取非标准化数据,以最小化xhr调用.如果存储是非规范化的,例如MessageStore将包含呈现消息所需的所有数据.每条消息都是如此
{
"id": 42
"message": "Héllo, you tried reactjs-flux too. Awesome isn't it!"
"user": {id: 1337, username: "amirouche", bio: "maker"},
"likes": [{id: 2600, username: "NinjaTurtle"}, {id: 2601, username: "Peer"}
}
Run Code Online (Sandbox Code Playgroud)
商店可能有责任(通过事件?)来使用部分用户模型更新UserStore.
我想到的另一种方法是使用一些规范化的存储,并使用视图所期望的模式创建特定的存储.
在这种情况下,在我看来,动作创建者只对调度有效载荷有用.这毫无用处.
你怎么看?
我是Flux/React的新手,我很难理解一些基本的架构决策:
不幸的是,我看到的所有例子似乎都太简单了,无法回答这些问题.让我们从Facebook的聊天应用示例开始吧.有多个线程,每个线程都有消息.MessageStore保存整个应用程序的所有消息,名为getAllForThread(id)的方法返回已过滤的消息子集.当消息进入任何线程时,它会发出更改通知,导致MessageSection react组件重新获取数据(无论用户正在查看哪个线程).这显然不会扩展.如果我们有10,000个线程,每个都有大量的消息活动怎么办?以下是我决定解决问题的方法:
我用这种方法离基地有多远?还有一种更简单的方法可以扩展吗?
我在reactjs-flux编写一个简单的应用程序,一切正常,除了我收到来自reactjs的警告,告诉我我在未安装的组件上调用setState.
我已经弄明白这是因为没有从商店中删除组件被挂钩的changelisteners componentWillUnmount.我知道这一点,因为当我打开监听器列表时,Eventemitter我会看到应该被销毁的监听器,并且当我多次挂载/卸载相同的组件时,列表会变大.
我从我的BaseStore粘贴代码:
import Constants from '../core/Constants';
import {EventEmitter} from 'events';
class BaseStore extends EventEmitter {
// Allow Controller-View to register itself with store
addChangeListener(callback) {
this.on(Constants.CHANGE_EVENT, callback);
}
removeChangeListener(callback) {
this.removeListener(Constants.CHANGE_EVENT, callback);
}
// triggers change listener above, firing controller-view callback
emitChange() {
this.emit(Constants.CHANGE_EVENT);
}
}
export default BaseStore;
Run Code Online (Sandbox Code Playgroud)
我从遇到此错误的组件中粘贴相关代码(但它适用于所有组件):
@AuthenticatedComponent
class ProductsPage extends React.Component {
static propTypes = {
accessToken: PropTypes.string
};
constructor() {
super();
this._productBatch;
this._productBatchesNum;
this._activeProductBatch;
this._productBlacklist;
this._searchById;
this._searchingById;
this.state = this._getStateFromStore(); …Run Code Online (Sandbox Code Playgroud) 我的application.react本机listView中有113条记录需要3秒多的时间才能呈现所有行.如何使其高效,以便时间消耗最小化,应用体验可以顺利进行.我在ios中检查了相同的应用程序,与react-native app版本相比,它效率更高.我每行都有一个头像图像和名称和按钮.
这是listview的代码
var Ziglist = React.createClass({
getInitialState: function() {
return {
isLoading: true,
resultsData: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 != row2 }),
};
},
componentWillMount: function(){
PeopleStore.listen(this.onChange);
PeopleActions.getPeopleFollowing();
},
componentWillUnmount() {
PeopleStore.unlisten(this.onChange);
},
onChange(state) {
this.setState({resultsData: this.getDataSource(state.resultsData)})
},
getDataSource: function(mediaItem: Array<any>): ListView.dataSource {
return this.state.resultsData.cloneWithRows(mediaItem)
},
render: function() {
return (
<View style={{flex: 1}} >
<ListView
dataSource={this.state.resultsData}
renderRow={this.renderRow}
renderSeperator={this.renderSeperator}
contentInset={{top: 0}}
automaticallyAdjustContentInsets={false}
/>
<Button
containerStyle={styles.goAhead}
style={styles.base}
onPress={() => this.onStartPress()}>
<Text style={[styles.base,styles.go]}>Ok, Lets GO > </Text>
</Button>
</View> …Run Code Online (Sandbox Code Playgroud) reactjs reactjs-flux react-native react-native-listview react-native-android
我有一个列表视图,我想在每行显示图像,我不想一次显示整个25个图像.我只是想加载来自视口的图像.
我在道具中获取网址
<Image source={{uri: this.props.media.image_url}}
style={{ width:this.props.media.width,
height: this.props.media.height}}
/>
Run Code Online (Sandbox Code Playgroud)
我怎样才能在本机中做到这一点.注意:我试过这些库,但没有一个适合我.可能是它为旧版本的反应版本编写的版本问题,其中一些不适用于动态道具
reactjs-flux ×10
reactjs ×9
flux ×3
javascript ×3
react-native ×2
image ×1
lazy-loading ×1
react-jsx ×1