背景:

举个例子:在显示动态的页面中删除某一条动态之后退出该页,当再进入该页之后这个被删除的动态是否还显示?
显示! 为啥? cache
cache是为了增强用户体验,如果每一次进入一个页面都需要从网络获取数据,当数据量很大时却迟迟加载不出来,麻爪了吧.....
但是现在cache的存在却给我们造成了很大的困扰:
我虽然删除了这条动态,并配合使用react-nativestate进行状态变化将这个动态在视觉上被删除掉了,但我没有重新获取数据,更新数据。当我从外界再次进入这个页面之后页面上显示的数据还是从cache中获取的数据。因此必须要更新cache!!

在前面的博客中提到,GraphQL是一个API查询语言,他可以将使用PostgreSQL写的server代码自动生成Query或者Mutation,非常的方便。而Apollo Client就是一个强大的JavaScript GraphQL客户端。对于cache,在Apollo Client中有着强大的管理策略。
在近阶段的使用过程中,我总结了两种管理缓存的办法:

  1. 手动更新缓存
  2. 自动更新缓存

一:手动更新缓存

在不断的搜索中我在文档中找到了他:
https://www.apollographql.com...

一个可以自定义访问,或者直接访问apollo缓存的指南

看到这的时候我似乎有些明白了,人家都给你说的很明白了。你管理缓存的方式有两种一种是自定义,另一种是自动。
fuck。武林秘籍都放在这,我却因为看不懂武林秘籍上的字迟迟不能升级????
应用场景:
如图一个消息隐藏的选择开关,当进行选择之后就会自动触发react-apollomutation操作,将这种变化传递到数据库,但是如果不更新缓存,当你退出本页面,再进来时就会发现消息隐藏的开关显示和原来还是一样的。因此需要进行缓存的更新。

第一段代码:GraphQL定义mutation

export const UPDATE_PERSON_SETTING = gql`
mutation updatePersonById($input: UpdatePersonByIdInput!) {updatePersonById(input: $input) {clientMutationIdperson {hideSpeaker}}
}
`

第二段代码: Mutation组件mutate操作
(请先阅读官网相关部分之后再看)

<Mutation mutation={UPDATE_PERSON_SETTING} variables={{ input: { id: currentPerson.id,personPatch: {hideSpeaker: true} } } }update={(cache, { data: { updatePersonById } }) => {this.updateCacheAfterSwitchHideSpeak(cache, updatePersonById.person.hideSpeaker)}}>{updatePersonById => (<Switch value={currentPerson.hideSpeaker} onValueChange={value => {updatePersonById({ variables: { input: { id: currentPerson.id,personPatch: {hideSpeaker: value} } } })}}/>)}</Mutation>

分析:
采用UPDATE_PERSON_SETTING这段GraphQL mutation操作在对开关进行更改,同时返回了更改后的数据hideSpeaker
Mutation这个组件中第三个参数update是一个箭头函数,函数的第一个参数是cache,第二个参数data是用来更改缓存的数据。这个data就来自于第一段代码中mutation操作的返回值。
在函数体中,调用用于更改缓存的函数updateCacheAfterSwitchHideSpeak,一并将cache和data传入其中。
接下来分析一下第三段代码
第三段代码:更新缓存函数

updateCacheAfterSwitchHideSpeak = (cache, value) => {const data = cache.readQuery({query: CURRENT_PERSON})data.currentPerson.hideSpeaker = valuecache.writeQuery({ query: CURRENT_PERSON, data })}

当接收到cache和value之后,输出一下cache,发现里面存在两个方法:readQuery,writeQuery,这两个方法就是我们用来进行读取缓存和更改缓存的办法。
注意:
这里的query参数必须要和渲染这个组件时所获取数据的query来源是一致的。
也就是说,必须是同一个GraphQL API。如果存在variables,那么variables也必须是一样的。
结合实际情况:在进入这个设置页面时,通过调用一个GraphQL 查询API并且将hideSpeaker查询出来,渲染出页面。而查询的结果也就形成了一个缓存。一个项目中有很多的查询,有些页面使用同一个GraphQL API进行查询,但是他们的condition却不同这就会造成cache的不同,因此在查询过程中如果存在variables,就必须进行严格的限制,确保从cachereadQuery出来的data就是你梦寐以求的那个Ta -_-。
下面是一段带有variables的readQuery代码

 const variables = {personPostCondition: { personId: personId },likeCondition: { personId: personId },orderBy: 'CREATED_AT_DESC'}const data = cache.readQuery({variables,query: PERSON_DYNAMICS})

在读取完cache中的data之后,你可以输出一下,看是不是当时你在渲染页面时query的数据,但是此时消息隐藏已经进行了调整,相应的hideSpeaker却还是false,此时单独将这个属性拿出来进行调整:data.currentPerson.hideSpeaker = value 在修改完后再使用writeQuery将新的cache写进去。此时就完成了cache的更改。

query和readQuery的区别
query的数据查询来源有两个:
1:服务器
2:缓存
readQuery的数据查询来源只有一个:
1:缓存
如果缓存中不存在,他就会报错,因此使用这个方法的前提就是已经使用了query将数据从服务器获取到了。

当然据官网上的描述,手动更改缓存的方式还有几种,但是目前还没有仔细的看过。日后再进行解释说明。

二:自动更新缓存

与手动更新相对的自然就是自动更新了。
既然有自动更新功能,他肯定是借助了什么逆天的“工具”!

apollo-cache-inmemory

这一点在官网也已经有了详细的说明了:

安排的明明白白的了,在Apollo Client 2.0apollo-cache-inmemory 他是默认实现的。因此,只要使用了Apollo Client 2.0npm时他是会进行相应的自动安装的。
缓存的标准化管理是实现自动更新缓存的前提!!!
inmemory是一个规范化的数据存储,他是咋规范化的呢???

query到数据之后,InMemoryCache对查询来的数据进行分割成单个的对象并保存。
而且为这些单个的对象都设置唯一的标识符,如果在query数据时将那些可以作为唯一标识符的字段例如id也一并获取到了,那么就将这个id作为分割后对象的唯一标识符。


上面这个简单的例子说明,如果id相同,那么score在缓存中的数据也会自动进行更新。
因此结合我们之前的实例做一个简单的更改:

export const UPDATE_PERSON_SETTING = gql`
mutation updatePersonById($input: UpdatePersonByIdInput!) {updatePersonById(input: $input) {clientMutationIdperson {idhideSpeaker}}
}
`

我们在进行mutation之后的返回值中存在id,这就符合上面的要求。他就会自动进行缓存的更新。
如果你还心存疑虑,你大可在readQuery后将data输出一下,此时你就会发现 hideSpeaker已经更改成目前的状态true。这就是自动更新的快捷之处。此时你就不必使用readQuery和writeQuery这种费时费力的方法了。

三:最后的话

1:不论是自动更新还是手动更新,都必须将更改之后的数据返回出来,就像hideSpeaker,更改他之后,你必须将它返回出来。这不论是在自动更新还是在手动更新上都是有必要的。
2:关于两者的选择使用,毫无疑问,通常情况下使用自动更新,特殊情况下使用手动更新,在明白原理后,有时你可以使用手动更新进行一些投机取巧的更新缓存的操作。
3:难,都难。爬,一起爬。

React Native项目使用react-apollo实现更新缓存的两种方式相关推荐

  1. java实现mysql自动更新创建时间与更新时间的两种方式

    一:通过数据库自身实现 1 .创建表的时候加上  create_time  与   update_time 两个字段 `create_time` timestamp NOT NULL DEFAULT ...

  2. Python pip更新教程(两种方式)

    1. 直接采用命令行模式更新 1.1 搜索框搜索cmd,然后以管理员模式打开 1.2 执行命令 python -m pip install --upgrade pip 1.3 查看更新后的版本 pip ...

  3. React native 项目进阶(redux, redux saga, redux logger)

    之前利用知乎日报的api写了react-native的一个入门项目,传送文章地址React Native 项目入门和源码地址RN入门项目源码,目前github上的代码已经在原文的基础上增加了新的功能, ...

  4. [置顶] 【稀饭】react native 实战系列教程之热更新原理分析与实现

    很多人在技术选型的时候,会选择RN是因为它具有热更新,而且这是它的一个特性,所以实现起来会相对比较简单,不像原生那样,原生的热更新是一个大工程.那就目前来看,RN的热更新方案已有的,有微软的CodeP ...

  5. react native 实战系列教程之热更新原理分析与实现

    很多人在技术选型的时候,会选择RN是因为它具有热更新,而且这是它的一个特性,所以实现起来会相对比较简单,不像原生那样,原生的热更新是一个大工程.那就目前来看,RN的热更新方案已有的,有微软的CodeP ...

  6. React Native 项目整合 CodePush 完全指南

    作者 | 钱凯 杏仁移动开发工程师,前嵌入式工程师,关注大前端技术新潮流. 本文使用的环境: React@16.3.1 React Native@0.55.4 react-native-code-pu ...

  7. 【腾讯Bugly干货分享】React Native项目实战总结

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/577e16a7640ad7b4682c64a7 "8小时内拼工作,8小 ...

  8. React Native 项目常用第三方组件汇总

    React Native 项目常用第三方组件汇总 https://www.jianshu.com/p/d9cd9a868764?utm_campaign=maleskine&utm_conte ...

  9. 技术实践丨React Native 项目 Web 端同构

    摘要:尽管 React Native 已经进入开源的第 6 个年头,距离发布 1.0 版本依旧是遥遥无期."Learn once, write anywhere",完全不影响 Re ...

最新文章

  1. The Human Touch 将人工智能和机器人用于病人工作的实际和伦理意义
  2. iframe 父页面与子页面之间的方法的相互调用
  3. dNet项目数据访问层代码总结
  4. 数据库原理与应用(SQL Server)笔记 第九章 存储过程和触发器
  5. 《Linux内核原理与分析》第六周作业
  6. linux系统监控和进程管理
  7. All Of ACM
  8. 力扣283,移动零(JavaScript)
  9. Lucas(卢卡斯)定理
  10. 手机APP测试主要有哪些内容
  11. linux更新系统内核,Linux内核升级方法详解
  12. 如何建立个人网站:从搭建到运营再到盈利
  13. 怎么设置计算机升级更新失败怎么办,windows update更新失败怎么办,教您windows update更新失败怎么办...
  14. 2016书单总结--看透SpringMvc源代码分析与实践-概述
  15. Unity出IOS包报错记 -1
  16. Python基础进阶
  17. Atom终端命令行插件
  18. 半同步半异步模式以及Leader_Follwer模式
  19. 2023CUPT第七题 法拉第波 思路和解法
  20. 2023全新个人免签约码支付系统PHP源码+ThinkPHP6框架/全开源的

热门文章

  1. Socket 套接字和解决粘包问题
  2. C# 基于 adb 控制安卓
  3. BZOJ.5093.[Lydsy1711月赛]图的价值(NTT 斯特林数)
  4. loj2291. 「THUSC 2016」补退选
  5. 2017.05.12_SAP特殊功能
  6. 利用UICollectionView实现瀑布流
  7. 学习simple.data之基础篇
  8. CSS的float和position
  9. [原创]c# 加解密通用类
  10. 机器学习基石PLA相关