如何将 HOC 转换为 apollo 的反应组件语法?

How to convert HOC to react component syntax for apollo?

任何人都可以帮助我理解如何抽象出 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);

使用我的应用程序同步设置创建 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 组件作为输入,并将 return 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

详细说明我的评论,并使用 <Query> 语法:

src/index.js中:

import React from "react";
import withData from "../lib/withData";
import TodosWithData from "../graphql/components/todos";

class App extends React.Component {
  render() {
    console.log("props: ", this.props);
    return (
      <div>
        <p>Hello World</p>
        <TodosWithData />
      </div>
    );
  }
}

export default withData(App);

src/graphql/components/todos.js中:

import React from "react";
import { Query } from "react-apollo";
import gql from "graphql-tag";

const query = gql`
  query listTodos {
    listTodos {
      items {
        id
        name
        completed
      }
    }
  }
`;

const TodosWithData = () => (
  <Query query={query} fetchPolicy="cache-and-network">
    {({ loading, error, data: { listTodos } }) => {
      if (error) return <div>Error loading todos</div>
      if (loading) return <div>Loading...</div>
      return (
        <div>
          <ul>
            {listTodos.items.map(todo => (
               <li key={todo.id}>{`${todo.name}${todo.completed ? " - DONE" : ""}`}</li>
            ))}
          </ul>
        </div>
      )
    }}
  </Query>
);

export default TodosWithData;