我的字段为什么是空值?
Relay 读取的字段可能为空的原因有很多,其中一些原因可能很模糊或不直观。在调试意外空值时,了解导致字段为空的常见情况和边缘情况可能会有所帮助。本文档列出了可能导致空值或缺失值的情况,并提供了一些技巧来帮助您确定您遇到的情况。
服务器返回空值
字段为空的最简单原因是服务器明确返回了空值。这可能发生在以下两种情况下:
- 服务器的字段解析器明确返回了空值
- 字段解析器抛出异常。在这种情况下,GraphQL 将为该字段返回空值。即使服务器解析器的返回类型是非空值,也是如此。唯一的例外是标注为非空的字段。在这种情况下,服务器决不应该返回空值。如果遇到异常,整个父对象将被置空。
🕵️♀️ 如何判断:使用 Relay Dev tools 或浏览器开发工具的网络选项卡检查服务器的响应,以查看字段是否为空。
图形关系更改
如果另一个查询/突变/订阅观察到图形中的关系更改,您最终可能会尝试从查询从未获取过的对象中读取字段。
假设您有一个查询来读取您最好的朋友的名字
query MyQuery {
me {
best_friend {
# id: 1
name
}
}
}
在您获得查询响应后,您最好的朋友是谁在服务器上发生了变化。然后,另一个查询/突变/订阅从best_friend
获取一组不同的字段。
query OtherQuery {
me {
best_friend {
# new id: 2
# Note: name is not fetched here
age
}
}
}
由于 Relay 存储是规范化的,我们将更新me
记录以表明best_friend
链接字段现在指向 ID 为 2 的用户,而我们知道的关于该用户的唯一信息是他们的年龄。
这将触发MyQuery
的重新渲染。但是,当我们尝试从 ID 为 2 的用户读取name
字段时,我们找不到它,因为我们知道的关于 ID 为 2 的用户的唯一信息是他们的age
。请注意,在这种情况下,关系“更改”也可能意味着一个新的关系。例如,如果您一开始没有最好的朋友,但后续响应返回了一些最好的朋友,但没有获取您的组件所需的所有字段。
注意:从理论上讲,Relay可以在遇到这种状态时重新获取您的查询,但一些查询不适合随意重新发布,更一般地说,UI 状态以不与直接用户操作相关联的方式发生更改会导致混乱。出于这个原因,我们选择不执行这种场景下的重新获取。
🕵️♀️ 如何判断:您可以在FragmentResource
中的readWithIdentifier
的最终返回语句处设置断点/console.log
(代码指针。这是我们在 Relay 中知道我们缺少数据,但没有查询正在进行获取它的点。
不一致的服务器响应
这是一种罕见的边缘情况,但如果服务器没有正确实现字段稳定性语义,则字段可能在响应的一部分中存在,但在另一部分中明确为空。
{
me {
id: 1
name: "Alice"
}
me_elsewhere_in_the_graph {
id: 1 # Note this is the same as the `me` field above...
name: null
}
}
在这种情况下,Relay 首先了解用户 1 的name
是 Alice,但随后在查询中发现用户 1 的name
现在为null
。由于 Relay 将数据存储在规范化的存储中,用户 1 只能对name
有一个值,Relay 将处于用户 1 的name
为null
的状态。
🕵️♀️ 如何判断:Relay 足够聪明,可以检测到这种情况发生,并将在控制台中记录错误,在开发模式下类似于:“RelayResponseNormalizer:无效记录。该记录包含同一个 ID 的两个实例:1,包含冲突的字段,name 及其值:Alice 和 null”。此外,您可以手动检查查询响应。
请注意,如果不稳定的字段是链接字段(指向另一个对象的边),这种类型的错误会导致在单个响应中发生图形关系更改(如上所述)。例如,如果具有相同id
的用户出现在响应中的两个位置,但他们的best_friend
在这两个位置有所不同。
🕵️♀️ 如何判断:Relay 也足够聪明,可以检测到这种情况,并在开发模式下显示类似的控制台警告。
客户端删除或更新不完整
命令式存储更新或乐观更新可能已删除记录或字段。如果命令式存储更新或乐观更新将新记录写入存储,它可能不会为您期望能够读取的字段提供值。这是一个基本问题,因为更新程序无法静态地知道可能从新对象访问的所有数据。
🕵️♀️ 如何判断:由于 React 和 Relay 的批处理,并非总是能够将组件更新与触发它的存储更新相关联。在这里,您最好的选择是在组件中设置断点,以查看您的值何时为空,然后使用 Relay Dev Tools 查看最后几次更新。
这可能是由于新创建的对象没有提供特定字段,或者如上所述,更新导致图形中出现新的或更改的关系。在这种情况下,请使用该部分中的“如何判断”提示。
此页面有用吗?
请帮助我们通过 回答几个简短问题来让网站更好.