React/Flux 存储不会改变它的状态
Posted
技术标签:
【中文标题】React/Flux 存储不会改变它的状态【英文标题】:React/Flux store doesn't change it's state 【发布时间】:2016-05-24 05:56:30 【问题描述】:从 2 周前开始,我的 React/Flux 应用程序出现问题。它是在 ES6 中完成的,使用 webpack 和 babel。
它实际上并没有进入 _onChange 方法内部,商店发出 change 事件。所以组件本身不会以修改后的状态再次渲染。
这里你可以看看我的组件:
import React from 'react';
import Item from 'components/item/item';
import Actions from './item-list.actions';
import Store from './item-list.store';
const StoreInstance = new Store();
class ItemList extends React.Component
constructor(props)
super(props);
this._onChange = this._onChange.bind(this);
this.state = this.getItemListState();
componentWillMount()
StoreInstance.addChangeListener(this._onChange);
Actions.requestFlats(Actions.setFlats);
componentWillUnmount()
StoreInstance.removeChangeListener(this._onChange);
_onChange()
this.setState(this.getItemListState);
getItemListState()
return
flats: StoreInstance.getFlats()
render()
return(
<ul className="item__list">
this.state.flats.map((flat, index) =>
<li className="col-xs-12 col-sm-12 col-md-6 col-lg-6">
<Item key=index flat=flat></Item>
</li>
)
</ul>
);
export default ItemList;
我的行动:
import AppDispatcher from 'services/dispacher/dispacher';
import Constants from './item-list.constants';
let ItemListActions =
getFlats: () =>
AppDispatcher.handleAction(
type: Constants.GET_FLATS,
data:
);
,
setFlats: (flats) =>
AppDispatcher.handleAction(
type: Constants.SET_FLATS,
data:
flats
);
,
requestFlats: (callback) =>
AppDispatcher.handleAction(
type: Constants.REQUEST_FLATS,
data:
callback
);
;
export default ItemListActions;
并存储:
import AppDispatcher from 'services/dispacher/dispacher';
import AppStore from 'services/store/store';
import Api from './item-list.api';
import Constants from './item-list.constants';
class ItemListStore extends AppStore
constructor()
super();
this.flats = [];
requestFlats(callback)
Api.getFlats(callback);
getFlats()
return this.flats;
setFlats(flats)
this.flats = flats;
const ItemListStoreInstance = new ItemListStore();
AppDispatcher.register((payload) =>
let action = payload.action;
switch (action.type)
case Constants.GET_FLATS:
ItemListStoreInstance.getFlats(action.data);
break;
case Constants.SET_FLATS:
ItemListStoreInstance.setFlats(action.data.flats);
break;
case Constants.REQUEST_FLATS:
ItemListStoreInstance.requestFlats(action.data.callback);
break;
default:
return true;
ItemListStoreInstance.emitChange();
);
export default ItemListStore;
AppStore 的延伸
import EventEmitter from 'events';
const CHANGE_EVENT = 'change';
class Store extends EventEmitter
constructor()
super();
emitChange()
this.emit(CHANGE_EVENT);
addChangeListener(callback)
this.on(CHANGE_EVENT, callback);
removeChangeListener(callback)
this.removeListener(CHANGE_EVENT, callback);
Store.dispatchToken = null;
export default Store;
我已经多次检查此代码并查看整个互联网上的示例,但我没有成功。
我想当我这样做时:
StoreInstance.addChangeListener(this._onChange);
商店会监听我的更改事件,但看起来没有。 当我从 API 中获取新数据时,我执行了 setFlats 并且没有执行 _onChange,因此 UI 上没有显示任何更改。
您在此代码中发现任何问题吗?有什么可以帮我解决的吗?
提前致谢。
【问题讨论】:
不需要绑定this
吗?!我觉得应该是StoreInstance.addChangeListener(this._onChange.bind(this));
是在构造函数上绑定的,后面就不用绑定了。
当然,我错过了!
但我发现了别的东西:this.setState(this.getItemListState);
应该是 this.setState(this.getItemListState());
没错,但我没弄明白,因为它没有进入 this._onChange 方法中,这意味着 change 事件在某种程度上不起作用
【参考方案1】:
我在任何地方都没有看到您使用 ItemListStore。您的组件正在使用“Store”类,该类仅扩展 EventEmitter。找不到与 ItemListStore 的连接。
这一行(在您的 ItemListStore 中):
ItemListStoreInstance.emitChange();
不会触发 Store 中的 emitChange() 方法。
【讨论】:
实际上你让我解决了这个问题,只是在 store 类中思考,真正的问题是它们是 2 个不同的实例。我将发布解决方案。 :) 非常感谢。【参考方案2】:问题实际上出在商店中,它返回 ItemListStore 而不是 ItemListStore 的实例,然后在组件中我有另一个实例,这就是为什么它不能相互通信。
这是 ItemListStore 的固定代码:
import AppDispatcher from 'services/dispacher/dispacher';
import AppStore from 'services/store/store';
import Api from './item-list.api';
import Constants from './item-list.constants';
class ItemListStore extends AppStore
constructor()
super();
this.flats = [];
requestFlats(callback)
Api.getFlats(callback);
getFlats()
return this.flats;
setFlats(flats)
this.flats = flats;
const ItemListStoreInstance = new ItemListStore();
AppDispatcher.register((payload) =>
let action = payload.action;
switch (action.type)
case Constants.GET_FLATS:
ItemListStoreInstance.getFlats(action.data);
break;
case Constants.SET_FLATS:
ItemListStoreInstance.setFlats(action.data.flats);
break;
case Constants.REQUEST_FLATS:
ItemListStoreInstance.requestFlats(action.data.callback);
break;
default:
return true;
ItemListStoreInstance.emitChange();
);
export default ItemListStoreInstance;
【讨论】:
以上是关于React/Flux 存储不会改变它的状态的主要内容,如果未能解决你的问题,请参考以下文章
将 Flux 存储中的 Immutable.js 映射与内部 React 组件状态合并
Vue,错误 [vuex] 不会在突变处理程序之外改变 vuex 存储状态