2016-11-28 25 views
0

我有一個控制器視圖調用,需要從兩個API端點獲取初始數據。第一部分是用戶身份驗證狀態,第二部分是項目列表,用於填充菜單。React Flux - 處理併發操作調用,避免「在調度中間調度」?

控制器視圖:

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; 

ItemStore:

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; 

AuthStore:

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; 

AuthAction

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; 

ItemAction

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

var ItemAction = { 
    getItems: function() { 
      ItemApi.getItems().then(
       function(response) { 
        AppDispatcher.handleServerAction({ 
         type: ItemConstants.GET_ITEMS_SUCCESS, 
         items: response.data 
        }); 
       } 
      ) 
      .catch(
       function(error) { 
        AppDispatcher.handleServerAction({ 
         type: ItemConstants.GET_ITEMS_FAILURE 
        }); 
       } 
      ); 
    } 
}; 

export default ItemAction; 

我將不包括API文件,因爲他們只是用做Axios公司到後端簡單的調用。一切正常,就我所能說的是Flux兼容,但我無法避免偶爾出現的錯誤「無法在派遣中發送」。

任何人都可以幫忙或告訴我,如果我做對了,我能做些什麼來防止發送錯誤?

回答

0

我見過一些例子,其中添加了代碼以避免多個同時發生的請求,如this StackOverflow threadthis blog post。第一個示例阻止對同一端點的同時請求,第二個示例在創建新請求時實際取消未決請求。