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 存储状态

三元运算符不改变状态

错误:[vuex] 不要在突变处理程序之外改变 vuex 存储状态。 NUXT

不使用突变直接改变 Vuex 状态

如何处理 React/Flux 中的保存状态?