React Native+Firebase+TS:数据类型与更新方式的技术疑问
问题解答
1. 是否需要分别定义带id和不带id的两种类型?
非常建议这么做,因为Firestore文档的ID属于文档引用属性,而非文档数据本身,拆分类型能让数据结构更清晰,避免冗余和类型混淆。
你可以这样定义:
// 对应Firestore文档内部的数据结构,不含ID type ProgramData = { name: string; trainings: Record<string, Training>; userId: string; }; // 前端状态管理用的类型,包含文档ID(可选是因为新建时还没有ID) type Program = ProgramData & { id?: string; };
这样在Firestore读写时只用ProgramData,Redux状态里存Program,类型职责明确,还能避免把ID意外写入文档。
2. 更新Program时,应传入currentEditingProgram对象还是仅传入id?
优先传入包含更新后数据的对象+ID,而不是只传ID。原因有两点:
- 只传ID的话,你还得重新从Firestore或Redux里查询最新的Program数据,多了一次不必要的操作;
- 你的项目有ProgramDetail跳转Training的场景,Redux里的
currentEditingProgram应该是维护了完整的带ID的对象,直接用这个对象拆分出数据和ID更高效。
修改你的thunk函数,让它接收明确的参数:
export const updateProgramById = createAsyncThunk( "programs/updateById", async ({ id, data }: { id: string; data: ProgramData }, thunkAPI) => { await updateDoc(doc(db, programsCol.id, id), data); // 返回完整的Program对象,方便同步更新Redux状态 return { id, ...data } as Program; } );
调用的时候从currentEditingProgram里解构出ID和数据:
// 确保currentEditingProgram不为null if (currentEditingProgram) { const { id, ...programData } = currentEditingProgram; await updateProgramById({ id: id!, data: programData }); }
这样既符合Firestore的要求,又能充分利用Redux里已有的状态数据,避免额外请求。
内容的提问来源于stack exchange,提问作者Romain Hoffmann
相关产品推荐
相关产品推荐

