Невозможно установить локальное состояние Apollo с вложенными значениями
Я тестирую Apollo Graphql с помощью React, и я пытаюсь обновить локальное состояние с помощью Apollo Graphql с вложенным объектом. У меня проблема. Данные возвращаютnull
value и даже не возвращает значение, которое я установил по умолчанию. Единственное предупреждение, которое я вижу, это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
метод, который является синхронным и вернет вам данные без обещания. Обратите внимание, что с помощью этого метода вы можете делать запросы только на стороне клиента, т.е. если вы хотите запрашивать поля клиента и сервера одновременно, он не будет работать.