我正在编写LoadingComponent
,在加载某些数据时应返回Spinner
,完成后应返回this.props.children
。
我在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
)
}
以下是我将state
与props
:
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;
}
};
问题是loadingUser
和loadingCurrencies
总是假的。这是getCurrencies
函数,当数据开始下载时以及在调度为false之后调度为true:
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
Redux Dev Tool未激活,它开始在LoadingComponent
个孩子处于活动状态。实际上,当我在reducer处设置断点时状态发生变化......在Redux Dev Tool开始激活之后,我可以观察到加载状态实际上已被改变为false - &gt;是的 - &gt;假。如果有人可以提供帮助,我将非常感激。
答案 0 :(得分:1)
我建议您在商店中添加redux-logger
:https://www.npmjs.com/package/redux-logger。这将有助于确定触发事件的顺序。
我最初的想法是,您可能会在loadCurrencies
和loadingCurrencies
之间返回竞争条件。如果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
})