Reputation: 2113
Could anyone help me understand how I can abstract away apollo graphQL logic to convert between using apollo with HOC versus using the more modern <Query>({data, loading})=>(<MyComponent data={data} loading={loading}/>)</Query>
syntax? Or if I can't do that, how you can use HOCs in a sub component that is not the whole page itself? I'm using next-apollo-appsync
to handle all of my graphQL issues:
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);
Once I create a withData function with my appsync settings, I use the withData function to create a TodosWithData function.
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;
This function will take a react component as an input and will return apollo wrapped around the component, and we'll have access to the data under this.props.data
, just like we'd expect. The weird thing is that I can get this dumb component below to work, but only if it is on the page level- it does not work if I move it to a component that I load from a page.
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);
Here is a working repo for reference. The actual error I get is Cannot read property 'apollo' of undefined
Upvotes: 0
Views: 336
Reputation: 9949
To elaborate on my comment, and using the <Query>
syntax:
In 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);
In 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;
Upvotes: 1