2017-11-25 131 views
3

我正在編寫LoadingComponent,當某些數據加載完成時它應該返回Spinner,並且應該返回this.props.childrenRedux調用dispach函數,但它不會更改商店

我在componentWillMount獲取數據:

class LoadingComponent extends React.Component { 
    componentWillMount() { 
     this.props.userActions.onUserAuthChange(); 
     this.props.currencyActions.getCurrencies(); 
    } 
} 

我檢查,如果用戶或貨幣,一個是加載如果是返回Spinner

render() { 
    const {loadingUser, loadingCurrencies} = this.props; 

    if (loadingCurrencies || loadingUser) { 
     return (
      <Spinner/> 
     ) 
    } 
    return (
     this.props.children 
    ) 
} 

這裏是我連接stateprops

const mapStateToProps = state => ({ 
    user: state.user, 
    loadingUser: state.loading.loadingUser, 
    loadingCurrencies: state.loading.loadingCurrencies, 
}); 

const mapDispatchToProps = dispatch => ({ 
    userActions: bindActionCreators(userActions, dispatch), 
    currencyActions: bindActionCreators(currencyActions, dispatch), 
}); 

const ConnectedLoading = connect(mapStateToProps, mapDispatchToProps) 
(LoadingComponent); 

export default withRouter(ConnectedLoading); 

loadingReducer

const loadingReducer = (state = initialState.loading, action) => { 
    switch (action.type) { 
    case actionTypes.LOADING: 
     return {...state, isLoading: action.loading}; 
    case actionTypes.LOADING_USER: 
     return {...state, loadingUser: action.loadingUser}; 
    case actionTypes.LOADING_CURRENCIES: 
     return {...state, loadingCurrencies: action.loadingCurrencies}; 
    default: 
     return state; 
    } 
}; 

的事情是,loadingUserloadingCurrencies總是假的。這是getCurrencies功能與真正當數據開始下載調度和虛假調度後:

export const getCurrencies =() => async dispatch => { 
    try { 
     dispatch(loadingCurrencies(true)); 
     const currencies = await get(); 
     dispatch(loadCurrencies(currencies.rates)); 
     dispatch(loadingCurrencies(false)); 
    } catch (e) { 

    } 
} 

我使用在App.js的LoadingComponent:

render() { 
    return (
     <LoadingComponent> 
      <div className='App'> 
       <Route path='/:lang' render={props => 
        languages.hasOwnProperty(props.match.params.lang) ? 
         <Navbar {...props}/> : 
         <Redirect to={`/${defaultLanguage}`}/>} 
       /> 
       <Layout/> 
      </div> 
     </LoadingComponent> 
    ) 
} 

這是減速功能,監聽loadCurrencies(currencies.rates)

const currencyReducer = (state = initialState.currency, action) => { 
    switch (action.type) { 
    case actionTypes.LOAD_CURRENCIES: 
     return {...state, currencies: action.currencies}; 
    case actionTypes.CHANGE_CURRENCY: 
     return {...state, current: action.current}; 
    default: 
     return state; 
    } 
} 

在調試過程中發現,在LoadingComponent的終極版開發工具是不是ACTIV e並開始在LoadingComponent的孩子身上活動。實際上,當我在reducer中設置斷點時,狀態會發生變化...並且在Redux Dev Tool開始啓動後,我可以觀察到加載狀態實際上已經被更改爲false - > true - > false。如果有人能提供幫助,我將非常感激。

+3

你能張貼聽'loadCurrencies(currencies.rates)'減速? –

+0

通過'connect()'連接您的加載組件到商店的部分在哪裏? – zer0chain

+0

當你的空捕獲被發現時會發生什麼?你應該刪除整個try/catch包裝 –

回答

1

我建議將redux-logger添加到您的商店:https://www.npmjs.com/package/redux-logger。這將有助於確定事件發生的順序。

我最初的想法是,你可能有一個競爭條件loadCurrenciesloadingCurrencies返回。如果loadCurrencies是承諾,那麼loadingCurrencies應該在then塊中發送,以指示承諾已經返回。

具有bool arg方法的IMO是一種代碼異味,並且由於加載狀態與實際的加載方法相關聯,所以加載成爲同一個reducer的一部分是有意義的。我通常遵循的模式是:

行動

export const getCurrencies =() => { 
    return dispatch => { 
    dispatch(requestCurrencies()) // loading: true 
    return api.getCurrencies() 
     .then(currencies => dispatch(receiveCurrencies(currencies))) 
    } 
} 

export const requestCurrencies =() => ({ 
    type: REQUEST_CURRENCIES, 
    loadingCurrencies: true 
}) 

export const receiveCurrencies = currencies => ({ 
    type: RECEIVE_CURRENCIES, 
    currencies, 
    loadingCurrencies: false 
})