我正在使用reducer检查各种动作状态,如成功,待定,错误等。我希望在延迟1秒后显示加载指示。如果响应在1s之前,那么我不想显示加载指示器。
目前,我没有更新挂起状态的加载状态,而是使用setTimeout从render函数触发一个动作。
在超时期限之前传递响应时会产生问题。我该如何解决这个问题?
reducer.js:
const initialState = {
error: false,
loading: false,
showModal: false,
};
export default function appReducer(state=initialState, action) {
if (action.type.endsWith('ERROR'))
return {
...state,
error: true,
loading: false,
showModal: true,
};
else if (action.type.endsWith('PENDING'))
return {
...state,
error: false,
loading: false,
};
else if (action.type.endsWith('SUCCESS'))
return {
...state,
error: false,
loading: false,
};
else if (action.type === errorModalActionTypes.CLOSE_MODAL.ACTION)
return {
...state,
showModal: false,
};
else if (action.type === loadingIndicatorActionTypes.UPDATE_LOADING.ACTION)
return {
...state,
loading: true,
};
else
return state;
}
saga.js
export function* getCollections(action) {
try {
yield put({ type: GET_COLLECTIONS.PENDING });
const collections = yield call(getCollectionsAPI);
yield put({ type: GET_COLLECTIONS.SUCCESS, collections });
} catch (error) {
yield put({ type: GET_COLLECTIONS.ERROR, error });
}
}
// These are the watchers that trigger the start of a saga
export default function* saga() {
yield fork(takeEvery, GET_COLLECTIONS.ACTION, getCollections);
}
LoadingIndicator.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { isLoading, hasError } from './selectors';
import { updateLoading } from './actions';
import LoadingIndicatorComponent from '../../../../components/loadingIndicator';
import './loadingIndicator.css';
export class LoadingIndicator extends Component {
render() {
console.log('called');
const { loading, error } = this.props;
if (!error)
setTimeout(this.props.updateLoading, 1000);
return (
<div className={`${loading && !error ? 'show' : 'hidden'}`}>
<LoadingIndicatorComponent>
Loading...
</LoadingIndicatorComponent>
</div>
);
}
}
const mapStateToProps = (state) => ({
loading: isLoading(state),
error: hasError(state),
});
export default connect(mapStateToProps, { updateLoading })(LoadingIndicator);
答案 0 :(得分:1)
鉴于您的架构,我建议的是:
+---------------------------+-----------------------------------------+-------------------------------------------+-------------------------------------------+---------------------------------------------+----------------------------------------------+------------------------------------------------+
| sku | embroidery_imprint_id_setup_sku_price_1 | embroidery_imprint_id_running_sku_price_1 | screen_print_imprint_id_setup_sku_price_1 | screen_print_imprint_id_running_sku_price_1 | laser_engraving_imprint_id_setup_sku_price_1 | laser_engraving_imprint_id_running_sku_price_1 |
+---------------------------+-----------------------------------------+-------------------------------------------+-------------------------------------------+---------------------------------------------+----------------------------------------------+------------------------------------------------+
| IP-205-1067-16 | NULL | NULL | 55 | 0.99 | 45 | 0.59 |
| IP-205-1067-16-39423495 | NULL | NULL | 55 | 0.99 | 45 | 0.59 |
| IP-205-1067-16-1272347 | NULL | NULL | 55 | 0.99 | 45 | 0.59 |
| IP-205-1067-16-56185 | NULL | NULL | 55 | 0.99 | 45 | 0.59 |
| IP-205-1067-16-1706399150 | NULL | NULL | 55 | 0.99 | 45 | 0.59 |
+---------------------------+-----------------------------------------+-------------------------------------------+-------------------------------------------+---------------------------------------------+----------------------------------------------+------------------------------------------------+
这里有几点需要注意:
export class LoadingIndicator extends Component {
constructor(props) {
super(props);
this.timeoutID = null;
this.state = {
showIndicator: false,
};
}
componentDidMount() {
this.ensureTimer(this.props);
}
componentWillUnmount() {
this.destroyTimer();
}
componentWillReceiveProps(props) {
if (props.loading !== this.props.loading || props.error !== this.props.error) {
this.ensureTimer(props);
}
}
ensureTimer(props) {
if (props.loading && !props.error) {
if (!this.timeoutID) {
this.timeoutID = setTimeout(() => {
this.timeoutID = null;
this.setState({showIndicator: true });
}, 1000);
}
} else {
this.destroyTimer();
}
}
destroyTimer() {
clearTimeout(this.timeoutID);
this.timeoutID = null;
this.setState({showIndicator: false });
}
render() {
const { loading, error } = this.props;
return (
<div className={`${this.state.showIndicator ? 'show' : 'hidden'}`}>
<LoadingIndicatorComponent>
Loading...
</LoadingIndicatorComponent>
</div>
);
}
}
const mapStateToProps = (state) => ({
loading: isLoading(state),
error: hasError(state),
});
export default connect(mapStateToProps, { updateLoading })(LoadingIndicator);
应该是纯函数的答案中得到答案。它不应该改变任何状态。相反,给予相同的道具和状态,它应该每次返回相同的东西(并且没有设置副作用)