Sas*_*sha 5 apollo reactjs graphql react-apollo apollo-client
我正在尝试将 Apollo 添加到应用程序中。我将使用它来获取数据,并希望遵循最佳实践并使用新的 API(从 Apollo 2.5 开始)来存储本地 UI 状态。
我一直在查看这些文档,但它们的 UI 状态比我想要实现的更简单。
我想移植我一直在 Redux 应用程序中使用的模式,其中许多 UI 元素的值集中存储。在 Redux 中,我有一个 reducer 对象用于存储我的 UI 值,如下所示:
{
dropdowns: {
someDropdown: [{ index: 0, value: 'Selected Value' }]
},
checkboxes: {
someCheckbox: true
}
}
Run Code Online (Sandbox Code Playgroud)
如在,不同类型的元素被表示为对象,其中每个键是 UI 元素的唯一 ID,值根据元素类型而变化。
我也对上述的扁平化版本持开放态度,其中没有按 UI 元素类型划分的子类别。
我还有一个单独的 reducer 存储一些 UI 元素的状态,例如:
{
openDropdownId: 'someDropdown',
openModalId: null
}
Run Code Online (Sandbox Code Playgroud)
至关重要的是,这些数据似乎包括其键不可预测的对象。我既不确定如何使用此类型输入
gql,也不确定如何有效地获取此数据(请参阅问题底部)。
我试过用 Apollo Client 重现这个,但遇到了很多错误。这是我的客户端设置:
例如,对于下拉菜单,其想法是在
states这里存储 open/closed state ,而values存储有关所选值的信息。
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import gql from 'graphql-tag';
const typeDefs = gql`
extend type UI {
states: Object
values: Object
}
`;
const defaults = {
ui: {
__typename: 'UI',
states: {},
values: {}
}
};
const cache = new InMemoryCache();
const client = new ApolloClient({
cache,
resolvers: {},
typeDefs
});
console.log({ defaults });
cache.writeData({ data: defaults });
export default client;
Run Code Online (Sandbox Code Playgroud)
然后我像这样使用那个客户端:
<ApolloProvider client={client}>
<App />
</ApolloProvider>
Run Code Online (Sandbox Code Playgroud)
这是引发错误的查询示例:
const QUERY = gql`
{
ui @client {
states
values
}
}
`;
Run Code Online (Sandbox Code Playgroud)
我看到的错误是:
Uncaught Invariant Violation: Missing selection set for object of type undefined returned for query field states该错误显示在 Query 组件中。
我还收到两个警告(可能一个 forstates一个 for values):
Missing field __typename in {}我是否需要以不同的方式构造我的数据才能像这样查询它?
后续问题:如果一个组件有一个 UID,那么能够查询它的值就好了,比如:
const QUERY = gql`
{
ui @client {
states {
${uid}
}
values {
${uid}
}
}
}
`;
Run Code Online (Sandbox Code Playgroud)
而不是获取所有UI 值,然后在组件中找到合适的值。
但是,这会引发错误:
Syntax Error: Invalid number, expected digit but got: "d".
Run Code Online (Sandbox Code Playgroud)
有没有办法执行这样的查询,或者有更好的方法来处理这一切?虽然这种数据结构可能不符合习惯,但似乎 Apollo 应该支持过滤查询,不是吗?
我也在 apollo 中尝试了本地状态管理,因此以下内容有些做作且非常晦涩,但它有效。
\n\n坦率地说 \xe2\x80\x94 所有不是标量或数组的东西都需要有一个类型。
\n\n所以这:
\n\nconst defaults = {\n ui: {\n __typename: 'UI',\n states: {},\n values: {}\n }\n};\nRun Code Online (Sandbox Code Playgroud)\n\n例如需要变成这样:
\n\nconst defaults = {\n ui: {\n __typename: 'UI',\n states: {\n __typename: 'UIStates'\n },\n values: {\n __typename: 'UIValues'\n }\n }\n};\nRun Code Online (Sandbox Code Playgroud)\n\n并且在您的查询中必须引用标量或数组,因此您的查询自然不会工作:
\n\nconst QUERY = gql`\n {\n ui @client {\n states\n values\n }\n }\n`;\nRun Code Online (Sandbox Code Playgroud)\n\n您需要更深入地定位标量或数组:
\n\nconst QUERY = gql`\n {\n ui @client {\n states {\n foo\n }\n values {\n bar\n }\n }\n }\n`;\nRun Code Online (Sandbox Code Playgroud)\n\n剩下的就看你的数据了。
\n\n如果您需要过滤查询 \xe2\x80\x94,您的查询将如下所示(第一个查询返回所有项目,下一个查询按 id 过滤项目):
\n\nconst TEST_CLIENT_FILTER_QUERY = gql`\n {\n bzz @client {\n id\n title\n }\n bzz(id: $id) @client {\n id\n title\n }\n }\n`\nRun Code Online (Sandbox Code Playgroud)\n\n您还需要一个解析器。这个非常脏,我不确定这是apollo-graphql方式,但它目前适合我的目的。
\n\n resolvers: {\n Query: {\n bzz: (root, variables, context) => {\n const key = context.getCacheKey({ __typename: 'bzz', id: variables.id })\n return context.cache.extract()[key]\n },\n },\n },\nRun Code Online (Sandbox Code Playgroud)\n\n这些是我对此类查询的默认设置:
\n\n cache.writeData({\n data: {\n bzz: [\n {\n __typename: 'bzz',\n id: 1,\n title: 'bzz 1',\n },\n {\n __typename: 'bzz',\n id: 2,\n title: 'bzz 2',\n },\n ],\n },\n })\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1103 次 |
| 最近记录: |