无法使用嵌套值设置 Apollo Local State

Cant Set Apollo Local State with nested values

我正在使用 React 测试 Apollo Graphql,我正在尝试使用带有嵌套对象的 Apollo Graphql 更新本地状态。我 运行 遇到了问题。数据 return 是一个 null 值,甚至不是 return 我设置为默认值的值。我看到的唯一警告是 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;

Name.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
    }
  }
`;

不幸的是,Apollo Client 的文档在这方面做得不好,只是开始使用 __typename 而没有直接正确解释其背后的原因。我以前见过其他工程师努力理解它的用途。正如警告所暗示的那样,您必须将 __typename 属性 传递给直接写入缓存的对象,因为 Apollo Client 默认情况下会在其内部数据规范化过程中使用此值 save/identify 数据。

在您对 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 -- 在函数组件的情况下,主体本身,因为 Promises 不是有效的 React 元素。所以你有两个选择:

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