【发布时间】:2019-06-16 08:34:30
【问题描述】:
谁能帮我理解如何抽象出 apollo graphQL 逻辑,以便在使用带有 HOC 的 apollo 与使用更现代的 <Query>({data, loading})=>(<MyComponent data={data} loading={loading}/>)</Query> 语法之间进行转换?或者,如果我不能这样做,您如何在不是整个页面本身的子组件中使用 HOC?我正在使用 next-apollo-appsync 来处理我所有的 graphQL 问题:
import { withAppSyncData } from "next-apollo-appsync";
import AppSyncConfig from "./aws-exports";
const config = {
url: AppSyncConfig.aws_appsync_graphqlEndpoint,
region: AppSyncConfig.aws_appsync_region,
auth: {
type: AppSyncConfig.aws_appsync_authenticationType,
apiKey: AppSyncConfig.aws_appsync_apiKey
}
};
export default withAppSyncData(config);
使用 appsync 设置创建 withData 函数后,我使用 withData 函数创建 TodosWithData 函数。
import withData from "../../lib/withData";
import gql from "graphql-tag";
import { graphql } from "react-apollo";
const query = gql`
query listTodos {
listTodos {
items {
id
name
completed
}
}
}
`;
const TodosWithData = MyComponent =>
withData(
graphql(query, {
options: {
fetchPolicy: "cache-and-network"
},
props: props => ({ todos: props.data.listTodos ? props.data.listTodos.items : [] })
})(MyComponent)
);
export default TodosWithData;
这个函数将一个 react 组件作为输入,并返回包裹在组件周围的 apollo,我们将可以访问 this.props.data 下的数据,就像我们期望的那样。奇怪的是,我可以让下面的这个愚蠢的组件工作,但前提是它在页面级别 - 如果我将它移动到我从页面加载的组件,它就不起作用。
import React from "react";
import TodosQuery from "../graphql/components/todos";
class Todos extends React.Component {
render() {
console.log(this.props); //We have access to the apollo payload
return (
<div>
<p>Static Text</p>
</div>
);
}
}
//This is what injects apollo payload into the Todos dumb-component.
export default TodosQuery(Todos);
这里有一个working repo 供参考。我得到的实际错误是Cannot read property 'apollo' of undefined
【问题讨论】:
-
我相信
withDataHOC必须应用于页面级别(src/index.js中的App组件)因为它调用getInitialProps,它只能在页面中使用,不能在子页面中使用组件。 -
使用
withData允许我将待办事项移动到不同的文件中,这是一个很好的开始!只要您在页面上保留withData,您是否可以使用<Query>语法?