Невозможно установить локальное состояние Apollo с вложенными значениями

Я тестирую Apollo Graphql с помощью React, и я пытаюсь обновить локальное состояние с помощью Apollo Graphql с вложенным объектом. У меня проблема. Данные возвращаютnullvalue и даже не возвращает значение, которое я установил по умолчанию. Единственное предупреждение, которое я вижу, это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
    }
  }
`;

1 ответ

Решение

К сожалению, документация Apollo Client не очень хороша в этом смысле и просто начинает использовать __typenameбез надлежащего объяснения причин, стоящих за этим. Я видел, как другие инженеры пытались понять его назначение. Как указано в предупреждении, вы должны пройти__typename для объектов, которые вы записываете непосредственно в кэш, поскольку Apollo Client будет использовать это значение по умолчанию в процессе внутренней нормализации данных для сохранения / идентификации данных.

На все твои звонки 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',
    },
  },
});

Кроме того, вы не можете использовать async/await на renderметод вашего компонента - в случае функциональных компонентов, само основное тело, поскольку промисы не являются действительными элементами React. Итак, у вас есть два варианта:

  • переключиться с client.query к useQueryкрючок; или
  • поскольку вы запрашиваете только поля на стороне клиента, вы можете использовать client.readQueryметод, который является синхронным и вернет вам данные без обещания. Обратите внимание, что с помощью этого метода вы можете делать запросы только на стороне клиента, т.е. если вы хотите запрашивать поля клиента и сервера одновременно, он не будет работать.
Другие вопросы по тегам