这是一个设计问题,但我想知道是否有处理此类情况的最佳实践。
我有一个react redux应用程序。应用程序状态结构如下所示:
{
groups: {gid1: group1, gid2: group2, ....},
expenses: {eid1: expense1, eid2: expense2, ...},
//.... the rest
}
这个
NewGroup
组件旨在创建新组。如果创建请求(对后端的ajax请求)成功,则会将其添加到处于应用状态的组列表中。这个
新建组
,这是一个模式,已关闭,组列表将更新。
尽管
新建组
如果请求未成功,则不应关闭组件。
主要的问题是:我是否应该将请求状态(如果成功或不成功,在后一种情况下的错误消息,如果结果返回或未返回,等等)合并到应用程序状态?这就是我真正怀疑的地方,因为它使应用程序状态非常丑陋、庞大,在某些情况下,它无法处理某些情况,在这种情况下:创建一个新组。
假设我将响应状态代码和错误消息添加到应用程序状态:
{
groups: {
newGroupId1: {
data: newGroupData1,// null in case it was not successful
isLoading: true/false, // if the call is returned or not
errorFetching: message1
}
}
}
在对后端的第二个不成功的create请求中,无法区分以前的调用和当前的调用,因为它们都有
errorFetching
和类似的
isLoading
价值观(例如,两者都有“未找到组”
错误获取
“false”表示
正在卸载
)
在以下情况下,区分请求调用的状态和应用程序状态中的真实数据的最佳做法是什么
redux
是否正在使用?
更新1
这是减速器:
import { FETCH_GROUPS_SUCCESS, FETCH_GROUPS_ERROR, CREATE_GROUP_SUCCESS, CREATE_GROUP_ERROR, DELETE_GROUP, FETCH_GROUP_SUCCESS, FETCH_GROUP_ERROR } from '../actions/creators';
export const FULL_GROUP = 'full_group';
export const SNIPPET_GROUP = 'snippet_group';
const INITIAL_STATE = {
data: null,
isLoading: true,
errorFetching: null
};
export default function(state=INITIAL_STATE, action) {
switch(action.type) {
case FETCH_GROUPS_SUCCESS:
return {
data: _.zipObject(_.map(action.payload, group => group.id),
_.map(action.payload, group => ({
data: group,
isLoading: true,
errorFetching: null,
mode: SNIPPET_GROUP
}))
),
isLoading: false,
errorFetching: null
};
case FETCH_GROUPS_ERROR:
return {
data: null,
isLoading: false,
errorFetching: action.payload.error
};
case FETCH_GROUP_SUCCESS:
return {
data: {...state.data, [action.payload.id]: {
data: action.payload,
isLoading: false,
errorFetching: null,
mode: FULL_GROUP
}},
isLoading: false,
errorFetching: null
};
case FETCH_GROUP_ERROR:
const stateWithoutId = _.omit(state, action.payload.id);
return {
data: {...stateWithoutId},
isLoading: false,
errorFetching: null
};
case CREATE_GROUP_SUCCESS:
debugger;
//TODO: how to let the NewGroup know that a group was created successfuly ?
return { ...state, [action.payload.id]: {
data: action.payload,
isLoading: true,
errorFetching: null,
mode: SNIPPET_GROUP
}};
default:
return state;
}
}
这是操作创建者:
export function groupsFetchSucceeded(response) {
return {
type: FETCH_GROUPS_SUCCESS,
payload: response
}
}
export function groupsFetchErrored(errorWithId) {
return {
type: FETCH_GROUPS_ERROR,
payload: errorWithId
}
}
export function groupCreateSucceeded(group) {
return {
type: CREATE_GROUP_SUCCESS,
payload: group
}
}
export function groupCreateErrored(errorWithId) {
return {
type: CREATE_GROUP_ERROR,
payload: response
}
}
export function groupFetchSucceeded(groupData) {
return {
type: FETCH_GROUP_SUCCESS,
payload: groupData
}
}
export function groupFetchErrored(errorWithId) {
//handle the error here
return {
type: FETCH_GROUP_ERROR,
payload: errorWithId
}
}
这是组件。拜托!不管这是一个redux表单,我不管它是不是redux表单,我只是在寻找一个大致的想法。你可以假设它是
react-redux
具有的组件
mapStateToProps
和
mapDispatchToProps
和其他相关的东西。
import { createGroup } from '../../actions';
import { validateName, validateDescription } from '../../helpers/group_utils';
import { renderField, validate } from '../../helpers/form_utils';
const validators = {
name: validateName,
description: validateDescription
};
class NewGroup extends Component {
_onSubmit(values) {
this.props.createGroup(values);
}
render() {
const { handleSubmit } = this.props;
return (
<div>
<form onSubmit={handleSubmit(this._onSubmit.bind(this))}>
<Field name="name" label="Name" type="text" fieldType="input" component={renderField.bind(this)}/>
<Field name="description" label="Description" type="text" fieldType="input" component={renderField.bind(this)}/>
<button type="submit" className="btn btn-primary">Create</button>
<button type="button" className="btn btn-primary" onClick={() => this.props.history.push('/group')}>Cancel</button>
</form>
</div>
);
}
}
export default reduxForm({
validate,
//a unique id for this form
form:'NewGroup',
validators
})(
connect(null, { createGroup })(NewGroup)
);