资讯专栏INFORMATION COLUMN

21 分钟学 apollo-client 系列:写入失败的原因和解决方案

Baoyuan / 1403人阅读

摘要:分钟学是一个系列,简单暴力,包学包会。一旦你丢失了,可能会导致写入失败,或者尽管写入了,但本该携带的那一层的数据没有写入。

21 分钟学 apollo-client 是一个系列,简单暴力,包学包会。

搭建 Apollo client 端,集成 redux
使用 apollo-client 来获取数据
修改本地的 apollo store 数据
提供定制方案

请求拦截

封装修改 client 的 api
apollo store 存储细节

写入 store 的失败原因分析和解决方案

大坑 - 写入数据失败

同志们注意啦!整个 apollo 的坑都集中在这里啦!

一旦返回的数据写入 apollo store 失败,会 静默失败 ,最终你发现怎么数据没有发生任何变化? (坑爹啊!)

一个简单的办法是,你去 node_modules 下,把报错信息暴露出来。是的,经过阅读源码,我发现这已经是最简单的办法了...

具体代码在 node_modulesapollo-clientdatawriteToStore.js


如果这解决了你的问题,请给我打赏,谢谢。

写入失败的原因

那什么时候会写入失败呢?

1. 写入的数据,其结构不符合 query schema
这意味着你不能基于 query schema 添加一些你本地需要的数据,比如 isSelected 什么的

2. 丢失 __typename 信息
不能丢失任何层级上的 __typename

当你 log fetchMoreResult 你会发现,它在很多层级上附带了 __typename ,这个数据用于检查写入数据是否匹配 query schema。
一旦你丢失了 __typename ,可能会导致写入失败,或者尽管写入了,但本该携带 __typename 的那一层的数据没有写入。

你可能说,那我当心一点,总是使用 Object.assign 或者 { ...obj, a: 1 } 这种 spread 赋值的方式吧。

年轻人,你还是太天真啊!

如果你得到一组数据,嵌套的某一个值为 null ,那么它本来就不携带 __typename
如果这个值为 null 的数据在你的 query schema 中确实需要 __typename,那即使你对这个数据重新赋值,也无法被写入到 apollo store 中,因为缺少 __typename 信息。

上面这段话比较绕,给你看个例子。

假设你有这样一个 query

query {
    user { # typename 为 User
        id
        nickname
        statistic { # typename 为 UserStatistic
            upvoted
        }
    }
}

然后,得到一组数据

const prev = {
    user: {
        __typename: "User",
        id: 1,
        nickname: "apollo 真是坑爹啊",
        statistic: null
    }
}

为了 ui 显示正常,你会给 statistic 设置一些默认值

const next = {
    ...prev,
    user: {
        ...prev.user,
        statistic: {
            upvoted: false,
        }
    }
}

如果你将 next 数据 writeToStore 你就会就发现 statistic 还是为 null,这些数据还是没有被写入 apollo store。

这是因为,user.statistic 在 schema 中定义的 type 是 UserStatistic,而原始数据由于为 null,所以本该自动附加的 __typename 属性也不存在。这导致你在写入 store 的时候,缺少了必要的 __typename 信息,apollo 将拒绝接受。

很扯吧。

要让上面的代码 work 起来,你需要

const next = {
    ...prev,
    user: {
        ...prev.user,
        statistic: {
            upvoted: false,
+            __typename: "UserStatistic",
        }
    }
}
总结

如果没有报错消息的话,上面这种情况是极其难以排查的,尤其是我们特别容易遇到缺少 __typename 的场景。

为了减少此类事故的发生,你可以

和后端协商,不要返回 null 值

不论何时何地,何种层级,永远给数据手动添加 __typename

不用 apollo








文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/91919.html

相关文章

  • 21 分钟 apollo-client 系列:获取数据

    摘要:分钟学是一个系列,简单暴力,包学包会。一旦组件挂载后,会自动进行数据请求,前提是客户端提供的和后端的相符。如果回调返回直接不作请求。在组件内进行分页请求之前提到了,这个装饰器为添加了对象,其中有个函数为。 21 分钟学 apollo-client 是一个系列,简单暴力,包学包会。 搭建 Apollo client 端,集成 redux使用 apollo-client 来获取数据修改本...

    robin 评论0 收藏0
  • 21 分钟 apollo-client 系列:修改本地 store 数据

    摘要:分钟学是一个系列,简单暴力,包学包会。搭建端,集成使用来获取数据修改本地的数据提供定制方案请求拦截封装修改的存储细节写入的失败原因分析和解决方案修改本地数据之前我们已经知道,我们可以在请求结束之后,通过自动执行的回调,修改。 21 分钟学 apollo-client 是一个系列,简单暴力,包学包会。 搭建 Apollo client 端,集成 redux使用 apollo-clien...

    617035918 评论0 收藏0
  • 21 分钟 apollo-client 系列:扩展 ApolloClient api

    摘要:分钟学是一个系列,简单暴力,包学包会。那怎么办呢本章就教你非常简单地实现扩展的。我们可以借鉴的的写法,为的实例添加一些自己的方法。更重要的是,也会有的效果,上一个的输出会成为下一个的输入,便于组合。 21 分钟学 apollo-client 是一个系列,简单暴力,包学包会。 搭建 Apollo client 端,集成 redux使用 apollo-client 来获取数据修改本地的 ...

    levy9527 评论0 收藏0
  • 21 分钟 apollo-client 系列:apollo store 存储细节

    摘要:分钟学是一个系列,简单暴力,包学包会。内部通过自己的私有没有暴露给开发者来更新这个。相当于这个就是自己维护的,它将所有通过得到的数据保存在这里。的生成规则根据官方文档的说法,在创建时,可选设置。如果不存在,则可能出现。 21 分钟学 apollo-client 是一个系列,简单暴力,包学包会。 搭建 Apollo client 端,集成 redux使用 apollo-client 来...

    lavor 评论0 收藏0
  • 21 分钟 apollo-client 系列:简单搭建

    摘要:分钟学是一个系列,简单暴力,包学包会。其中提到了等需要后端配合的东西,徒增了配置的复杂性。如果不行,再跟随我的简单步骤试试。环境要求请确保你已经搭建了自己的环境下文在行号前添加表示删除的原代码,表示新增的代码。 21 分钟学 apollo-client 是一个系列,简单暴力,包学包会。 搭建 Apollo client 端,集成 redux使用 apollo-client 来获取数据...

    ranwu 评论0 收藏0

发表评论

0条评论

Baoyuan

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<