GraphQL 片段:让每个组件拥有自己的数据

GraphQL 查询起初看起来很简洁。一个请求就能获取所有数据。但随着应用的增长……

你的页面查询开始为许多不同的子组件收集字段。你为新组件添加了一个字段。六周后你删除了那个组件,却忘记从主查询中移除该字段。现在没人知道删除它是否安全。查询会无限膨胀。

片段(Fragments)解决了这个问题。大多数团队将其作为复制粘贴字段的一种方式,但这是错误的用法。片段应该作为一种组件所有权的模型。

片段是针对特定类型的一组命名的字段。

示例:

fragment UserBadge on User {
  id
  name
  avatarUrl
}

你可以将此片段展开(spread)到任何需要 User 的查询中。

真正的价值在于你将片段保存在哪里。不要把它们放在共享文件中,而是将片段放在使用它的组件所在的同一个文件中。

这被称为“同地化”(co-location)。每个组件声明自己的数据需求。

当组件需要一个新字段时,你只需将其添加到该组件的片段中,父查询就会自动更新。当你删除一个组件时,也删除它的片段,查询就会随之缩小。父组件不需要知道其子组件的内部字段。

数据掩码(Data masking)让这一切变得更好。启用掩码后,组件只能看到它在自己的片段中请求的字段。即使服务器发送了额外的数据,你的组件也无法访问。

这创建了一个严格的契约:

  • TypeScript 准确地知道每个组件拥有哪些数据。
  • 如果你从片段中移除一个字段,TypeScript 会向你显示所有错误。
  • 重构变成了一个简单的类型检查过程,而不是在整个代码库中进行搜索。

在以下情况下使用片段:

  • 多个组件使用相同的类型(如 UserProduct)。
  • 你的页面查询太长。
  • 你在查询中意外留下了无用字段。
  • 你希望为数据提供 TypeScript 安全保障。

从小处着手。找一个从父查询获取数据的组件,将其字段移入一个片段中,并将该片段放在组件文件中。

随着应用的增长,片段能确保你的数据获取与 UI 保持一致。

Source: https://dev.to/grimicorn/graphql-fragments-let-each-component-own-its-data-5359