Skip to content

Instantly share code, notes, and snippets.

@xonlly
Last active November 23, 2017 13:29
Show Gist options
  • Save xonlly/cb2e31e81cce58e878eb442b9ccebf09 to your computer and use it in GitHub Desktop.
Save xonlly/cb2e31e81cce58e878eb442b9ccebf09 to your computer and use it in GitHub Desktop.
<ApolloQuery query={...} parser={data => data} variables={{ a: 'hello' }}>{parsedData => <div>{...}</div>}</ApolloQuery>
import { Component } from 'react';
import PropTypes from 'prop-types';
// wait apollo 2.1
export default class ApolloQuery extends Component {
state = { data: undefined, rest: {}, loading: false };
componentWillMount() {
const { query, variables } = this.props;
this.query(query, variables);
}
componentWillReceiveProps(nextProps) {
const { variables } = this.props;
const needUpdate = Object.keys(nextProps.variables).some(
key => nextProps.variables[key] !== variables[key],
);
if (nextProps.query !== this.props.query) this.updateQuery(nextProps.query);
if (
needUpdate ||
Object.keys(nextProps.variables).length !==
Object.keys(this.props.variables)
) {
this.refetch(nextProps.variables);
}
}
componentWillUnmount() {
// need a real unSubscribe, no method exist ?
// https://www.apollographql.com/docs/react/reference/#ObservableQuery
delete this.observableQuery;
}
query = (query, variables) => {
const { watchQuery } = this.context.client;
this.setState({ loading: true });
if (!this.observableQuery) {
this.observableQuery = watchQuery({ query, variables });
this.observableQuery.subscribe({
next: result => {
const { parser } = this.props;
const { data } = result;
const parsedData = parser ? parser(data) : data;
this.setState({ data: parsedData, result, loading: false });
},
});
} else {
this.observableQuery.refetch(variables);
}
};
// need upgrade ?
// https://www.apollographql.com/docs/react/reference/#ObservableQuery.updateQuery
updateQuery = (query = this.props.query) => {
return this.observableQuery.updateQuery(() => query);
};
refetch = (variables = this.props.variables) => {
return this.observableQuery.refetch(variables);
};
fetchMore = (...args) => {
return this.observableQuery.fetchMore(...args);
};
render() {
const { children } = this.props;
const { data, rest, loading } = this.state;
return children(data, {
refetch: this.refetch,
fetchMore: this.fetchMore,
...rest,
loading,
});
}
}
ApolloQuery.contextTypes = { client: PropTypes.object.isRequired };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment