我会坚持使用 REST api 调用,但在 redux 操作开始时伪造更新,除了可能在成功时向对象添加适当的 id 并仅在失败时恢复状态之外什么都不做。
在创建项目操作的情况下,您的减速器看起来像这样:
export default (state = {}, action) => {
switch (action.type) {
case ActionsTypes.CREATE_START:
// make the temporary changes
case ActionsTypes.CREATE_SUCCESS:
// update the previous temporary id with a proper id
case ActionsTypes.CREATE_FAILURE:
// delete the temporary changes
default:
return state;
}
};
你的行为是这样的:
const ActionLoading = item => ({
type: ActionsTypes.CREATE_START,
item,
});
const ActionSuccess = item => ({
type: ActionsTypes.CREATE_SUCCESS,
item ,
createdItem,
});
const ActionFailure = item => ({
type: ActionsTypes.CREATE_FAILURE,
item,
});
export default todo => (dispatch) => {
dispatch(ActionLoading(item)); // add the item to your state
const updatedTodo = await TodoClient.create(todo)
if (updatedTodo) {
dispatch(ActionSuccess(item, createdItem)) // update the temp item with a real id
} else {
dispatch(ActionFailure(item)) // remove the temporary item
}
};
出于性能考虑,您必须为正在管理的数据提供临时 id,并让对地图中呈现的项目做出正确的反应。我个人使用lodash的uniqueId。
您还必须为更新和删除实现此行为,但基本相同:
- 存储更改,更新您的对象而无需等待 api 和
失败时恢复更改。
- 在不等待 api 的情况下删除您的对象,并在失败时将其弹出。
这将给人一种实时的感觉,因为所有内容都会立即更新,并且只会在出现非托管错误时恢复。如果你足够信任你的后端,这就是要走的路。
编辑:刚刚看到您的更新,您可以坚持这种改变数据的方式(或在成功时更新状态的正常方式),但为了避免过多的复杂性和渲染时间,请确保您使用存储数据keyBy。一旦您的项目被存储为一个由其 id 键入的对象数组,您将能够以 O(1) 的复杂性添加、删除和修改它们。此外,react 会理解它不需要重新渲染整个列表,而只需重新渲染单个更新的项目。