我对redux thunk的实现导致覆盖数组数据。
显然流程中有问题,但我无法弄清楚。
基本上,我有两个组件 StringInstrument 和 UsersListedItems 。
StringInstrument 将(通过axios)从数据库中获取数据以获取项目所有者的列表。
将为每个所有者创建一个 UsersListedItems 组件,该组件还将通过所有者ID从数据库(图像)中获取数据。
所以我想说 StringInstrument 实际上是创建 UsersListedItems 。
以下是 StringInstrument 的一些代码:
if (this.props.error) {
return <p>Sorry! There was an error loading the items</p>;
}
if (this.props.isLoading) {
return <CircularProgress/>;
}
return (
<div>
<Grid container spacing={24}>
{this.props.itemOwner.map((item, index) => (
<Grid item xs={6} sm={3} key={index}>
<UsersListedItems
ownerId={item.ownerId}
userName={item.userName}
categoryId={1}>
</UsersListedItems>
</Grid >)
)}
</Grid>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
itemOwner: state.itemOwner.data,
isLoading: state.itemOwner.isLoading,
error: state.itemOwner.error
}
}
const mapDispatchToProps = (dispatch) => {
return {
getItemOwners: (id) => dispatch(itemAction.getItemOwners(id))
}
这就是我实施动作和减速器的方式。
export function getItemOwner(state = initState, action) {
switch (action.type) {
case GET_ITEM_OWNER_START:
state = Object.assign({}, state, { isLoading: true });
break;
case GET_ITEM_OWNER_SUCCESS:
state = Object.assign({}, state, { data: action.payload, isLoading: false });
break;
case GET_ITEM_OWNER_ERROR:
state = Object.assign({}, state, { error: action.payload, isLoading: false });
break;
}
return state;
}
export function getItems(state = initState, action) {
switch (action.type) {
case GET_ITEMS_START:
state = Object.assign({}, state, { isLoading: true });
break;
case GET_ITEMS_SUCCESS:
state = Object.assign({}, state, { data: action.payload, isLoading: false });
break;
case GET_ITEMS_ERROR:
state = Object.assign({}, state, { error: action.payload, isLoading: false });
break;
}
return state;
export const getItemOwners = (categoryId) => {
return (dispatch, getState) => {
//make async call to database
dispatch({ type: GET_ITEM_OWNER_START });
axios.get('api/items/owner/category/' + categoryId)
.then(function (response) {
dispatch({ type: GET_ITEM_OWNER_SUCCESS, payload: response.data });
})
.catch(function (error) {
dispatch({ type: GET_ITEM_OWNER_ERROR, payload: error });
});
}
};
export const getItems = (categoryId, ownerId) => {
return (dispatch, getState) => {
dispatch({ type: GET_ITEMS_START });
axios.get('api/items/' + categoryId + '/' + ownerId)
.then(function (response) {
dispatch({ type: GET_ITEMS_SUCCESS, payload: response.data });
})
.catch(function (error) {
dispatch({ type: GET_ITEMS_ERROR, payload: error });
});
}
我不确定如何按顺序管理\控制调度程序的流程,以便它适合组件结构而不覆盖所收集的数据。
如您在附件图像中看到的,在末尾有4个“ GET_ITEM_SUCCESS”,其中每个将覆盖下一个。
希望这个长代码示例对我很清楚,并表示歉意。
谢谢
答案 0 :(得分:0)
我认为您遇到的问题是,您在任何给定时间都只存储一个处于状态的项目,而每个后续调用都会破坏处于状态的内容。如果我对此假设是正确的,那么解决方案将是使用categoryId和ownerId作为将数据存储在对象中的键,该对象的值将是有效负载。
首先,您需要在操作中提供categoryId和ownerId
export const getItems = (categoryId, ownerId) => (dispatch, getState) => {
dispatch({ type: GET_ITEMS_START, categoryId, ownerId });
axios.get('api/items/' + categoryId + '/' + ownerId)
.then(function (response) {
dispatch({ type: GET_ITEMS_SUCCESS, payload: response.data, categoryId, ownerId });
})
.catch(function (error) {
dispatch({ type: GET_ITEMS_ERROR, payload: error, categoryId, ownerId });
});
下一步,您需要更新化简器以将有效负载分配给对象
const key = `${action.categoryId}-${action.ownerId}`; // unique key for the payload
switch (action.type) {
case GET_ITEMS_START:
state = Object.assign({}, state, { isLoading: true, data: Object.assign({}, state.data, {[key]: []}) });
break;
case GET_ITEMS_SUCCESS:
state = Object.assign({}, state, { data: Object.assign({}, state.data, { [key]: action.payload }), isLoading: false });
break;
case GET_ITEMS_ERROR:
state = Object.assign({}, state, { error: action.payload, isLoading: false });
break;
}
最后,您需要通过props(redux)将数据映射到组件的状态。然后,您可以使用相同的关键项访问这些项[${categoryId}-${ownerId}