如何同步网页客户端和数据库?创建于客户端实体和处理标识
问题描述:
比方说,我试图保持项目的大名单,与Web UI提供了增加新的可能性。 我的架构是一个Web UI(React/Redux)+数据库/服务器(Graph.cool)。
现在当我添加一个新项目时,我可以做的就是简单地运行“创建”查询,取回带有其数据库ID的项目,并将项目存储在一个对象中,该项目通过ID索引所有项目。
问题:网络可能很慢/脱机,请求可能会失败,我仍然希望能够立即向用户显示他在列表中新创建的项目,并稍后与数据库同步。
问题
我需要一个解决方案,让我先在本地创建的项目,后来更换数据库ID本地ID当响应回来。 我该怎么做?
答
最简单的方法是在对象上创建某种localKey
字段,并按照惯例将其添加到您的商店。
只要后端完成处理并且事件进入,而不是将新对象添加到存储中,则使用localKey
查找本地副本并将其替换。
答
原来,这是我的代码组织/ Redux的问题。
我无法弄清楚如何实现某种形式的解决方案就像砥Ø建议,因为:
- 如果我率先打响请求我没有办法附上LOCALID并用它找回来响应跟踪它
- 如果我在reducer中首先创建本地项目,我无法将localID传递给执行请求的部分,并存储从响应中提取的项目/我认为从一个减速器
我做了什么我nstead这似乎运作良好,是:
- 大火,被在后台
- 劳动者创造LOCALID并将其传递到两个新的行动拾起成为工人的第一个动作:一个用于创建本地用于发射的请求到数据库
这里的项目,一个是我的代码解决方案,与终极版+英雄传奇+纳基+经典的待办事项列表例如:
export default kea({
path:() => ["kea", "taskStore"],
actions:() => ({
addTask: title => ({ title }),
storeLocalTask: (localId, title) => ({ localId, title }),
storeDBTask: (localId, task) => ({ localId, task }),
setTasks: tasks => ({ tasks }),
fetchTasks:() => ({})
}),
*start() {
const { fetchTasks } = this.actions;
yield put(fetchTasks());
},
reducers: ({ actions }) => ({
indexedTasks: [
{},
PropTypes.object,
{
[actions.setTasks]: (state, payload) => indexById(payload.tasks),
[actions.storeLocalTask]: (state, payload) => {
const { localId, title } = payload;
return { ...state, [localId]: { localId, title } };
},
[actions.storeDBTask]: (state, payload) => {
const { localId, task } = payload;
const { [localId]: _dispose_, ...rest } = state;
return { ...rest, [task.id]: task };
}
}
]
}),
takeLatest: ({ actions, workers }) => ({
[actions.fetchTasks]: workers.fetchTasks,
[actions.addTask]: workers.createTask
}),
workers: {
*fetchTasks() {
const res = yield db.query({
query: gql`
query {
allTasks {
id
title
}
}
`
});
const { setTasks } = this.actions;
yield put(setTasks(res.data.allTasks));
yield delay(1000);
},
*createTask(action) {
const { storeLocalTask, storeDBTask } = this.actions;
const { title } = action.payload;
const localId = randomString();
yield put(storeLocalTask(localId, title));
const res = yield db.mutate({
mutation: gql`
mutation($title: String!) {
createTask(title: $title) {
id
title
}
}
`,
variables: { ...action.payload }
});
yield put(storeDBTask(localId, res.data.createTask));
yield delay(1000);
}
}
});
原来这是鳕鱼的问题e组织/ Redux我有。请参阅下面的答案。现在我的问题不像我想的那么清楚/有用,我应该删除它吗? (或以某种方式改进它?) –