博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
21 分钟学 apollo-client 系列:写入失败的原因和解决方案
阅读量:7257 次
发布时间:2019-06-29

本文共 1833 字,大约阅读时间需要 6 分钟。

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

提供定制方案

大坑 - 写入数据失败

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

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

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

具体代码在 node_modules\apollo-client\data\writeToStore.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

转载地址:http://mdvdm.baihongyu.com/

你可能感兴趣的文章
时变网络置乱算法实现
查看>>
mysql创建账号
查看>>
C#中base关键字的几种用法
查看>>
TCP连接的状态详解以及故障排查
查看>>
高度 传递一样,计算出来的 不一样,
查看>>
fiddler常识汇总
查看>>
【转】Android SQLite 事务处理
查看>>
你真的懂SDWebImage?
查看>>
C# Stream篇(七) -- NetworkStream
查看>>
第九讲 文件系统管理
查看>>
WinDBG help
查看>>
【HDOJ】1310 Team Rankings
查看>>
第三次冲刺学习
查看>>
企业架构基本概念及发展历史
查看>>
把tomcat中的jar包倒入到myeclipse中
查看>>
SpringBoot使用拦截器/ Servlet/ Filter
查看>>
所思所想 需求分析
查看>>
安装FreeIPA以及应用时报错汇总
查看>>
SpringMVC+Hibernate框架快速搭建
查看>>
JSONObject数组排序工具类
查看>>