为什么选择 Apollo 客户端?
为什么选择 Apollo 客户端来管理你的数据?
Apollo 客户端 是一个状态管理库,通过 GraphQL 简化了远程和本地数据的处理。Apollo 客户端的智能缓存和对数据获取的声明式方法可以帮助你更快迭代,同时写出更少的代码。此外,如果您需要自定义功能,您可以在 Apollo 客户端的扩展之上构建您的理想客户端。
让我们直接看看 Apollo 客户端能为您带来什么! 🚀
声明式数据获取
Apollo 客户端处理从开始到结束的整个请求周期,包括跟踪加载和错误状态。在您的第一个请求之前,无需设置任何中间件或样板代码,您无需担心转换或缓存响应。您只需描述组件所需的数据,让 Apollo 客户端去完成繁重的工作。 💪
Apollo 客户端useQuery
钩子利用 React 的 Hooks API 将一个 查询 绑定到组件上,使该组件能够立即渲染查询的结果。useQuery
钩子封装了获取您的数据的逻辑,跟踪加载和错误状态,并更新您的 UI。这种封装使将查询结果集成到您的表示组件变得轻而易举!
下面是 Apollo Client 在 React 中的实际应用示例:
function ShowDogs() {const { loading, error, data } = useQuery(GET_DOGS);if (error) return <Error />;if (loading) return <Fetching />;return <DogList dogs={data.dogs} />;}
在上面的例子中,我们使用useQuery
钩子从我们的GraphQL服务器拉取狗的信息并列出它们。当数据返回后,我们的<DogList />
组件将响应性地更新以显示新数据。
在切换到Apollo Client后,你会发现你可以移除许多与数据管理相关的先前代码。一些团队报告已经删除了数千行代码!
尽管使用Apollo Client时你会编写更少的代码,但这并不意味着你必须在功能上做出妥协。useQuery
钩子支持诸如乐观UI、重新获取和分页等高级功能。
结合本地与远程数据
成千上万的开发者告诉我们,Apollo Client在管理远程数据方面表现优秀,满足了他们约80%的数据需求。但本地数据(例如全局标志或设备API结果)怎么办?这占了整个数据的另外20%。
Apollo Client内置本地状态管理功能,允许您将Apollo缓存作为应用程序数据的单一真理来源。
通过使用Apollo Client的本地状态功能,您可以在同一个查询中包含本地字段和远程获取的字段:
const GET_DOG = gql`query GetDogByBreed($breed: String!) {dog(breed: $breed) {images {urlidisLiked @client}}}`;
在上面的例子中,我们正在查询我们的本-only字段isLiked,同时从我们的GraphQL服务器获取数据。您的组件包含本地和远程数据;现在,您的查询也可以!
通过使用Apollo Client管理您的数据,您可以利用GraphQL作为所有数据的统一接口。Apollo Client Devtools,您可以使用GraphiQL检查您本地和远程模式。
零配置缓存
缓存一个图并不是一件容易的事情,但我们已经为此花费了数年去解决问题。我们发现规范化是维护应用程序中多个组件之间一致数据的关键。
Apollo客户端区别于其他数据处理解决方案的其中一个关键特性是其本地、内存中的规范化缓存。
Apollo客户端的缓存很容易上手,并且可以在使用过程中进行配置。
import { ApolloClient, InMemoryCache } from '@apollo/client';const client = new ApolloClient({cache: new InMemoryCache(),});
一旦您将缓存传递给ApolloClient
,每当Apollo客户端接收到query的响应数据时,它会自动尝试识别并存储查询中的数据中的独特对象(即具有__typename属性和一个id属性的)到其缓存中独立的条目。
让我们看看一些实际例子,看看这种缓存机制如何使您的应用程序更高效。
以下query,GET_ALL_DOGS
,获取狗的列表以及每只狗的信息:
const GET_ALL_DOGS = gql`query GetAllDogs {dogs {idbreeddisplayImage}}`;
以下mutation,UPDATE_DISPLAY_IMAGE
,更新指定狗的displayImage并返回更新后的狗:
const UPDATE_DISPLAY_IMAGE = gql`mutation UpdateDisplayImage($id: String!, $displayImage: String!) {updateDisplayImage(id: $id, displayImage: $displayImage) {iddisplayImage}}`;
当我们运行UPDATE_DISPLAY_IMAGE
mutation时,我们希望确保狗的图片在应用程序的每个地方都进行了更新。我们还需要确保更新该狗的相关已缓存数据。
我们的UPDATE_DISPLAY_IMAGE
mutation返回被mutation修改的对象(即狗的id
和displayImage
),允许Apollo客户端自动覆盖具有相同id
的任何先前缓存的场的现有字段。将所有这一切结合起来,如果在Apollo客户端运行UPDATE_DISPLAY_IMAGE
mutation之前已经运行了GET_ALL_DOGS
query,它将自动在我们的本地缓存中更新更改狗的displayImage
。
有关使用mutations更新缓存的更多示例,请参阅直接更新缓存。
后台更新我们缓存的能力还可以帮助我们在想要避免我们缓存中已经包含的信息重新拉取的情景中。
例如,假设我们想导航到特定狗的详细信息页面。这个query看起来是这样的:
const GET_DOG = gql`query GetDog {dog(id: "abc") {idbreeddisplayImage}}`;
如果在某个时刻运行了上述 GET_ALL_DOGS
查询,那么我们的 GET_DOG
查询的数据可能已经存在于我们的本地缓存中。我们可以告诉 Apollo Client 首先在哪里查找缓存中的任何 Dog
对象,以避免重复检索信息,如果它已经在我们的缓存中存在。
下面我们定义了一个自定义的 FieldPolicy
,它返回对之前缓存的 Dog
对象数据的引用:
import { ApolloClient, InMemoryCache } from '@apollo/client';const cache = new InMemoryCache({typePolicies: {Query: {fields: {dog(_, { args, toReference }) {return toReference({__typename: 'Dog',id: args.id,});},},},},});const client = new ApolloClient({ cache });
上面的 字段策略 允许我们的 GET_DOG
查询直接从我们的缓存中读取之前存储的数据,而不是发送不必要的查询。
了解 Apollo Client 中的缓存。。
充满活力的生态系统
Apollo Client 的入门非常简单,但在需要构建更多高级功能时也非常灵活。如果您需要 @apollo/client
不提供自定义功能,您可以使用 Apollo Link 的架构创建自己的理想客户端,通过在 Apollo Client 上构建扩展来实现。
我们一直在惊叹贡献者基于 Apollo Client 建立的内容。以下是我们的社区的一些扩展:
apollo3-cache-persist
:简化 Apollo 缓存的持久化(@jamesreggio)。apollo-storybook-decorator
:使用 Apollo Client 包装您的 React Storybook stories(@abhiaiyer91)。- AppSync by AWS: Amazon的实时GraphQL客户端使用Apollo Client作为其底层.
apollo-augmented-hooks
: 为Apollo Client的hooks(appmotion)添加额外功能。apollo-cache-policies
: 通过支持高级缓存策略扩展Apollo Client的缓存(NerdWalletOSS)。
当您选择使用Apollo Client来管理数据时,您也将获得我们出色的社区支持。我们社区有数千名开发者,他们在社区论坛中分享想法。
您还可以阅读在经常更新的Apollo博客上关于最佳实践和公告的文章。
案例研究
从企业到初创公司,无数公司信任Apollo Client为其最关键的Web和原生应用提供动力。如果您想了解如何过渡到GraphQL和Apollo如何简化工程师的工作流程并改善公司的产品,请查看以下案例研究:
- 《纽约时报》:了解《纽约时报》如何从Relay切换到Apollo,并在其应用程序中实现SSR和持久查询等功能。
- Express:使用Apollo的易用分页功能帮助Express电子商务团队优化了关键产品页面。
- 美国职业足球大联盟:MLS从Redux切换到Apollo进行状态管理,使他们删除了几乎所有Redux代码。
- Expo:使用Apollo开发他们的React Native应用程序使Expo工程师能够专注于改进他们的产品,而不是编写数据抓取逻辑。
- 荷兰航空公司KLM:了解KLM团队如何使用GraphQL和Apollo扩展他们的Angular应用程序。
如果您的公司在生产中使用Apollo Client,我们很乐意在我们的博客上展示一个案例研究!请通过我们的社区论坛联系我们,以便我们了解更多您如何使用Apollo。或者,如果您已经有了想要在此展示的博客文章或会议演讲,请提交一个PR。