无法使用嵌套值设置 Apollo 本地状态

Posted

技术标签:

【中文标题】无法使用嵌套值设置 Apollo 本地状态【英文标题】:Cant Set Apollo Local State with nested values 【发布时间】:2020-01-19 23:05:59 【问题描述】:

我正在使用 React 测试 Apollo Graphql,并尝试使用带有嵌套对象的 Apollo Graphql 更新本地状态。我遇到了一个问题。数据返回一个null 值,甚至不返回我设置为默认值的值。我看到的唯一警告是Missing field __typename。我不确定我遗漏了什么,或者这不是您使用 Graphql 或 Apollo 问题正确设置嵌套值的方式。我有一个代码沙箱,其中包含我正在尝试做的示例https://codesandbox.io/embed/throbbing-river-xwe2y

index.js

import React from "react";
import ReactDOM from "react-dom";
import ApolloClient from "apollo-boost";
import  ApolloProvider  from "@apollo/react-hooks";
import App from "./App";

import "./styles.css";

const client = new ApolloClient(
  clientState: 
    defaults: 
      name: 
        firstName: "Michael",
        lastName: "Jordan"
      
    ,
    resolvers: ,
    typeDefs: `
      type Query 
        name: FullName
      

      type FullName 
        firsName: String
        lastName: String
      
    `
  
);

client.writeData(
  data: 
    name: 
      firstName: "Kobe",
      lastName: "Bryant"
    
  
);

const rootElement = document.getElementById("root");
ReactDOM.render(
  <ApolloProvider client=client>
    <App />
  </ApolloProvider>,
  rootElement
);

App.js

import React from "react";
import Name from "./Name";
import  useApolloClient  from "@apollo/react-hooks";

function App() 
  const client = useApolloClient();

  client.writeData(
    data: 
      name: 
        firstName: "Lebron",
        lastName: "James"
      
    
  );
  return (
    <div>
      <Name />
    </div>
  );


export default App;

名称.js

import React from "react";
import  NAME  from "./Queries";
import  useApolloClient  from "@apollo/react-hooks";

const Name = async props => 
  const client = useApolloClient();
  const  loading, data  = await client.query( query: NAME );
  console.log(data);

  return <div>Hello data.name.firstName</div>;
;

export default Name;

QUERIES.js

import gql from "graphql-tag";

export const GET_NAME = gql`
  
    name @client 
      firstName
      lastName
    
  
`;

【问题讨论】:

【参考方案1】:

不幸的是,Apollo Client 的文档在这种方式下并不好,直接开始使用__typename 没有正确解释其背后的原因。我以前见过其他工程师努力理解它的目的。正如警告所暗示的,您必须将 __typename 属性传递给您直接写入缓存的对象,因为 Apollo 客户端将在其内部数据规范化过程中默认使用此值来保存/识别数据。

在您对client.writeData 的所有调用中,您应该包含一个__typename 属性,例如:

client.writeData(
  data: 
    name: 
      __typename: 'FullName', // this is the name of the type this data represents, as you defined in your typeDefs
      firstName: 'Lebron',
      lastName: 'James',
    ,
  ,
);

另外,你不能在你的组件的render 方法上使用async/await——在功能组件的情况下,主体本身,因为 Promise 不是有效的 React 元素。所以你有两个选择:

client.query切换到useQuery钩子;或 由于您只请求客户端字段,因此您可以使用同步的client.readQuery 方法,并且无需Promise 即可将数据返回给您。请注意,使用此方法您只能发出客户端请求,即,如果您想同时请求客户端和服务器字段,它将不起作用。

【讨论】:

以上是关于无法使用嵌套值设置 Apollo 本地状态的主要内容,如果未能解决你的问题,请参考以下文章

无法在单个 GraphQL 查询中组合本地和远程数据(Next.js + Apollo)

Apollo Client 3.0 或 Redux 用于本地状态管理?

将嵌套对象写入本地 Apollo 缓存

GraphQL 突变后的 updateQueries 无法与 Apollo 客户端一起使用

GraphQL 突变后的 updateQueries 无法与 Apollo 客户端一起使用

Apollo 客户端本地状态 - LoggedIn 查询