You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apollo 3 React本地状态无法读取GraphQL自定义类型响应式变量

问题根因

你遇到的自定义类型字段读取返回null的问题,核心是3个配置错误:

  • 字段策略配置位置错误:你在Query.user的typePolicy里写了__typename: 'User',这个配置不属于字段策略的合法属性,__typename是存储的对象本身携带的元信息,不需要在策略里手动声明,无效配置会干扰Apollo的正常解析。
  • 响应式变量初始值类型不匹配:userVar初始值设为空字符串"",但后续存储的是用户对象,类型不一致会导致Apollo初始化字段时的异常。
  • 本地查询不符合GraphQL规范:GET_LOCAL_USER查询只声明了user @client,没有选择对象类型下的任何子字段。GraphQL规范要求对象类型的查询必须明确指定要返回的子字段,标量类型(比如你正常运行的isAuthenticated是Boolean标量)不需要子字段,这也是为什么布尔值查询正常、用户对象查询返回null的核心原因。
修复步骤
  1. 修正cache.js配置
    • 把userVar初始值从空字符串改为null,匹配未登录时无用户数据的状态,和后续存储的对象类型统一
    • 删除user字段策略里错误添加的__typename配置项,你从登录接口拿到的result.data.login.user本身已经自带__typename: 'User'字段,不需要手动声明
      修正后的cache相关代码:
import { InMemoryCache, makeVar, gql } from '@apollo/client'

export const isAuthenticatedVar = makeVar(!!localStorage.getItem('token'))
// 初始值改为null
export const userVar = makeVar(null)

export const cache = new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        isAuthenticated: {
          read() {
            return isAuthenticatedVar()
          }
        },
        user: {
          read() {
            return userVar()
          },
          // 删除此处错误的__typename配置
        }
      }
    }
  }
})

export const IS_AUTHENTICATED = gql`
  query IS_AUTHENTICATED {
    isAuthenticated @client
  }
`
  1. 补全本地查询的子字段
    修改GET_LOCAL_USER查询,明确声明你需要获取的User类型下的子字段,和你typeDef里定义的字段保持一致即可:
export const GET_LOCAL_USER = gql`
  query GET_LOCAL_USER {
    user @client {
      id
      name
      surname
      email
      phone
      isAdmin
      isCoach
      isManager
      # 按需添加你需要使用的其他字段,比如adress
    }
  }
`
  1. (可选)修正typeDef声明
    如果你本地定义的User类型不是扩展自服务端已有的User类型,把extend type User改为type User即可;如果服务端接口本身已经返回过User类型,保留extend写法没有问题。

改完之后再调用client.readQuery({ query: GET_LOCAL_USER })就能正常拿到存储的用户对象,不会再返回null。

内容的提问来源于stack exchange,提问作者Dylan Di Vito

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 16:36:43