GraphQL 片段:让每个组件拥有自己的数据
GraphQL 查询起初看起来很简洁。一个请求就能获取所有数据。但随着应用的增长……
你的页面查询开始为许多不同的子组件收集字段。你为新组件添加了一个字段。六周后你删除了那个组件,却忘记从主查询中移除该字段。现在没人知道删除它是否安全。查询会无限膨胀。
片段(Fragments)解决了这个问题。大多数团队将其作为复制粘贴字段的一种方式,但这是错误的用法。片段应该作为一种组件所有权的模型。
片段是针对特定类型的一组命名的字段。
示例:
fragment UserBadge on User {
id
name
avatarUrl
}
你可以将此片段展开(spread)到任何需要 User 的查询中。
真正的价值在于你将片段保存在哪里。不要把它们放在共享文件中,而是将片段放在使用它的组件所在的同一个文件中。
这被称为“同地化”(co-location)。每个组件声明自己的数据需求。
当组件需要一个新字段时,你只需将其添加到该组件的片段中,父查询就会自动更新。当你删除一个组件时,也删除它的片段,查询就会随之缩小。父组件不需要知道其子组件的内部字段。
数据掩码(Data masking)让这一切变得更好。启用掩码后,组件只能看到它在自己的片段中请求的字段。即使服务器发送了额外的数据,你的组件也无法访问。
这创建了一个严格的契约:
- TypeScript 准确地知道每个组件拥有哪些数据。
- 如果你从片段中移除一个字段,TypeScript 会向你显示所有错误。
- 重构变成了一个简单的类型检查过程,而不是在整个代码库中进行搜索。
在以下情况下使用片段:
- 多个组件使用相同的类型(如
User或Product)。 - 你的页面查询太长。
- 你在查询中意外留下了无用字段。
- 你希望为数据提供 TypeScript 安全保障。
从小处着手。找一个从父查询获取数据的组件,将其字段移入一个片段中,并将该片段放在组件文件中。
随着应用的增长,片段能确保你的数据获取与 UI 保持一致。
Source: https://dev.to/grimicorn/graphql-fragments-let-each-component-own-its-data-5359
