React Flux - 处理并发动作调用,避免在调度过程中调度"?

时间:2016-11-28 20:44:12

标签: reactjs reactjs-flux

我有一个名为的控制器视图,需要从两个API端点获取初始数据。第一部分是用户身份验证状态,第二部分是项目列表,用于填充菜单。

控制器视图:

transformValue()

ItemStore:

import React, { PropTypes } from 'react';
import BaseComponent from '../../Components/Base';
import Menu from '../../Components/App/Menu';
import ItemAction from '../../Actions/Items/ItemAction';
import AuthAction from '../../Actions/Auth/AuthAction';
import ItemStore from '../../Stores/Items/ItemStore';
import AuthStore from '../../Stores/Auth/AuthStore';

class App extends BaseComponent {
    constructor(props) {
        super(props);

        this.state = {};

        this._bind('getAuth', 'getItems');
    }

    componentWillMount() {
        AuthStore.addChangeListener(this.getAuth);
        ItemStore.addChangeListener(this.getItems);
    }

    componentDidMount() {
        AuthAction.check();
        ItemAction.getItems();
    }

    componentWillUnmount() {
        AuthStore.removeChangeListener(this.getAuth);
        ItemStore.removeChangeListener(this.getItems);
    }

    getAuth() {
        this.setState(AuthStore.getState());
    }

    getItems() {
        this.setState(ItemStore.getState());
    }

    render() {
        const { user, items } = this.state;

        const childrenWithProps = React.Children.map(this.props.children,
            (child) => React.cloneElement(child, {
                user: user,
                items: items
            })
        );

        return (
            <div>
                <Menu user={user} items={items}/>
                { childrenWithProps }
            </div>
        );
    }
}

App.propTypes = {
    params: PropTypes.object.isRequired,
    query: PropTypes.object
};

export default App;

AuthStore:

import AppStore from '../AppStore';
import AppDispatcher from '../../Dispatcher/AppDispatcher';
import ItemApi from '../../Utils/API/Items/ItemApi';
import ItemConstants from '../../Constants/Items/ItemConstants';

var appState = {
    items: undefined,
    isLoading: false
};


class ItemStore extends AppStore {
    constructor() {
        super();
    }

    reset() {
        appState = {};
    }

    getState() {
        return appState;
    }
}

let storeInstance = new ItemStore();

storeInstance.dispatchToken = AppDispatcher.register(payload => {
    var action = payload.action;

    switch(action.type) {
        case ItemConstants.GET_ITEMS_SUCCESS:
            appState = {
                items: action.data
            };
            break;

        case ItemConstants.GET_ITEMS_FAILURE:
            appState = {
                items: {}
            };
            break;

        default:
            return;
    }

    storeInstance.emitChange();
});

export default storeInstance;

AuthAction

import AppStore from '../AppStore';
import AppDispatcher from '../../Dispatcher/AppDispatcher';
import AuthApi from '../../Utils/API/Auth/AuthApi';
import AuthConstants from '../../Constants/Auth/AuthConstants';

var appState = {
    user: undefined,
    isLoading: false
};


class AuthStore extends AppStore {
    constructor() {
        super();
    }

    reset() {
        appState = {};
    }

    getState() {
        return appState;
    }
}

let storeInstance = new AuthStore();

storeInstance.dispatchToken = AppDispatcher.register(payload => {
    var action = payload.action;

    switch(action.type) {
        case AuthConstants.GET_USER_SUCCESS:
            appState = {
                user: action.user
            };
            break;

        case AuthConstants.GET_USER_FAILURE:
            appState = {
                user: undefined
            };
            break;

        default:
            return;
    }

    storeInstance.emitChange();
});

export default storeInstance;

ItemAction

import AppDispatcher from '../../Dispatcher/AppDispatcher';
import AuthApi from '../../Utils/API/Auth/AuthApi';
import AuthConstants from '../../Constants/Auth/AuthConstants';
import Jwt from '../../Utils/Jwt';

var AuthAction = {
    check: function() {
        if (Jwt.tokenIsValid()) {
            AuthApi.get().then(
                function(response) {
                    AppDispatcher.handleServerAction({
                        type: AuthConstants.GET_USER_SUCCESS,
                        user: response.data
                    });
                }
            )
            .catch(
                function(error) {
                    AppDispatcher.handleServerAction({
                        type: AuthConstants.GET_USER_FAILURE
                    });
                }
            );
        } else {
            AppDispatcher.handleServerAction({
                type: AuthConstants.GET_USER_FAILURE
            });
        }
    }
};

export default AuthAction;

我不会包含API文件,因为他们只是使用Axios对后端进行简单调用。一切正常,据我所知,与Flux兼容,但我不能避免偶然出现错误&#34;无法在发货过程中发送&#34;。

任何人都可以帮忙或告诉我,我是否正确行事以及如何防止发送错误?

1 个答案:

答案 0 :(得分:0)

我已经看到了一些示例,其中添加了代码以避免多个同时发出的请求,例如this StackOverflow threadthis blog post。第一个示例阻止对同一端点的同时请求,第二个示例实际上在创建新请求时取消挂起的请求。