[英]React + Flux: Getting initial state into a store
我们最近从Angular切换到React + Flux来构建一个相当复杂的业务应用程序。
采用一个容器组件将所有状态作为属性传递给组件树的方法不是为我们开发应用程序的实用方法,因为应用程序使用大型页面模式。 足够的状态确实传递给他们将模型加载到他们的商店的模态。
我遇到的问题是我需要将一些初始状态(作为道具传递下来)放入模态组件的商店中。 在这篇文章中 ,Facebook上的好人说,当同步不是目标时,可以使用道具作为初始状态。
这就是我目前将初始状态输入我的商店的方式:
var ABC = React.createClass({
...
getInitialState: function() {
return ABCStore.getInitialABCState(this.props.initialA);
},
...
var ABCStore = Reflux.createStore({
...
init: function() {
_state = {
a: null,
b: 'B init',
c: 'C init'
};
},
getInitialABCState: function(initialA) {
_state.a = initialA;
return _state;
},
getABCState: function() {
return _state;
}
...
我不确定这样做的最佳做法是什么,或者这是否是Flux反模式?
您使用getInitialState()
来更改商店的状态对我来说是错误的。 你应该至少在componentWillMount
这样做。
我会在componentWillMount
触发一个动作,并让商店处理程序更新商店的内部状态(这应该总是如此)。 然后,组件的商店更改处理程序可以使用您当前称为“初始状态”的任何数据
Reflux.listenTo
在你提供第三个参数时执行此操作,并且Reflux.connect
mixin factory(在引擎盖下使用Reflux.listenTo
)会自动为您处理。 这是一个例子:
var Actions = Reflux.createActions({"doIt"});
var Store = Reflux.createStore({
listenables: [Actions],
init: function() {
this.state = "I like to";
},
onDoIt: function() {
this.state = "Do it";
this.trigger(this.state);
},
getInitialState: function() {
return this.state;
}
});
var DoItButton = React.createClass({
mixins: [Reflux.connect(Store, "label")],
onClick: function() {
Actions.doIt();
},
render: function() {
return (<div onClick={this.onClick}>{this.state.label}</div>);
}
});
像其他海报所说的那样,最好的办法是在componentWillMount
触发一个动作。 在ES6中,这通常使用constructor
完成。
以下是如何使用ES6执行此操作的示例:
(请注意, AuthorActions.initAuthors()
依赖于实现,这只是一个示例。这可以从数据库获得初始状态。但最重要的是,此操作应该将具有初始状态的有效负载分派给调度程序)
var _authors = [];
var AuthorStoreInstance;
class AuthorStore extends EventEmitter {
constructor(props) {
super(props);
}
init() {
AuthorActions.initAuthors();
this.emitChange();
}
addChangeListener(cb) {
this.on(CHANGE_EVENT, cb);
}
removeChangeListener(cb) {
this.removeListener(CHANGE_EVENT, cb);
}
emitChange() {
this.emit(CHANGE_EVENT);
}
getAllAuthors() {
return _authors;
}
addAuthor(author) {
_authors.push(author);
this.emitChange();
}
setAuthors(authors) {
_authors = authors;
}
};
AuthorStoreInstance = new AuthorStore();
Dispatcher.register((action) => {
switch(action.actionType) {
case ActionTypes.CREATE_AUTHOR:
AuthorStoreInstance.addAuthor(action.author);
break;
case ActionTypes.INITIALIZE:
AuthorStoreInstance.setAuthors(action.initialData.authors);
break;
default:
//do nothing
}
});
AuthorStoreInstance.init();
export default AuthorStoreInstance;
注意init函数不是构造函数的一部分。 这是因为authorStore被创建时,为回调AuthorActions.initAuthors
尚未与调度员注册。
在向调度程序注册回调之后,应该进行初始化。
编辑:为清楚起见, initAuthors
看起来像这样:
initAuthors() {
var authors = AuthorAPI.getAllAuthors();
Dispatcher.dispatch({
actionType: ActionTypes.INITIALIZE,
initialData: {
authors: authors
}
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.