Не могу установить локальное состояние Аполлона с вложенными значениями - PullRequest
1 голос
/ 19 сентября 2019

Я тестирую Apollo Graphql с помощью React и пытаюсь обновить локальное состояние с помощью 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;

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 Ответ

0 голосов
/ 20 сентября 2019

К сожалению, документация клиента Apollo не подходит для этой цели и просто начинает использовать __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 hook;или
  • , поскольку вы запрашиваете только поля на стороне клиента, вы можете использовать синхронный метод client.readQuery, который вернет вам данные без обещания.Обратите внимание, что с помощью этого метода вы можете делать запросы только на стороне клиента, т. Е. Если вы хотите запрашивать поля клиента и сервера одновременно, он не будет работать.
...