【发布时间】:2018-07-11 07:09:50
【问题描述】:
对于我的 React 组件,我使用 Redux (react-redux) 和 Redux Thunk 来维护应用程序状态。
有一个ShowGroup 组件从后端检索group。如果组不存在(或任何其他错误情况),则会调用错误回调来更新状态。
class ShowGroup extends Component {
constructor(props) {
super(props);
this.groupId = this.props.match.params.id;
this.state = {
'loaded': false,
'error': null
};
}
_fetchGroupErrorCallback = response => {
this.setState({loaded: true, error: response});
}
componentDidMount() {
this.props.fetchGroup(this.groupId, this._fetchGroupErrorCallback);
}
render() {
//what is the best practice here ?
let group = this.props.groups[this.groupId];
if (!group) {
if (!this.state.loaded) {
return <div>Loading group ....</div>;
}
if (this.state.error) {
return <div>{this.state.error.data.message}</div>;
}
}
return (
<div className="show-group">
<form>
{_.map(FIELDS, renderField.bind(this))}
</form>
</div>
);
}
}
function mapStateToProps(state) {
return { groups: state.groups };
}
const mapDispatchToProps = (dispatch) => {
return {
fetchGroup: (id, callback) => dispatch(fetchGroup(id, callback)),
updateGroup: (id) => dispatch(updateGroup(id))
};
};
export default reduxForm({
validate,
//a unique id for this form
form:'ShowGroup',
fields: _.keys(FIELDS),
fields_def: FIELDS
})(
connect(mapStateToProps, mapDispatchToProps)(ShowGroup)
);
(这是一个redux-form 组件,没关系)
export function fetchGroup(id, fetchErrorCallback) {
return (dispatch) => {
axios.get(URL, AUTHORIZATION_HEADER)
.then(response => {
dispatch(groupFetched(response))
})
.catch(({response}) => {
fetchErrorCallback(response);
dispatch(groupFetchErrored(response));
})
};
}
groupFetchedErrored动作创建者:
export function groupFetchErrored(response) {
//handle the error here
return {
type: FETCH_GROUP_ERROR,
response
}
}
还有减速机:
export default function(state=INITIAL_STATE, action) {
switch(action.type) {
//....
case FETCH_GROUP_ERROR:
return _.omit(state, action.response.data.id);
default:
return state;
}
}
问题:
A. 如果出现错误响应,组件会被渲染 3 次:
1.第一次加载(在ajax调用之后)
2._fetchGroupErrorCallback被调用并设置状态,导致渲染
3. groupFetchErrored 被调度,导致另一个渲染
B. 如果响应成功,组件会被渲染两次,但状态不正确,因为没有任何更新(我认为为其添加回调是不正确的)
在将 Redux 和 Redux-Thunk 与 React 结合使用时,处理 ajax 错误响应的最佳实践是什么? action creator 和 reducer 应该如何通知组件有问题?
更新 1
这是我的根减速器:
const rootReducer = combineReducers({
form: formReducer,
groups: groupReducer
});
export default rootReducer;
如你所见,我有groups,它是一个表单对象:
{
groupId1: groupData1,
groupId2, groupData2,
....
}
所以,另一个问题是,我应该如何指定一个组正在加载(我不能在 groups 级别上使用 isLoading 或 errorFetching,添加一个条目似乎不是一个好主意对于每个无效的组 id 用户都可以尝试。或者也许有一种方法可以将无效的组 id 放在地图中然后清理它?不过我不知道应该在哪里发生这种情况。
【问题讨论】:
-
为什么要同时使用 state 和 props?让 props 成为唯一的真实来源,根本不使用状态。
-
听起来不错,但是
fetchGroup应该如何告诉组件服务器响应错误?
标签: reactjs redux react-redux