react-apollo-graphql
Version:
Get rid of decorators and use Apollo GraphQL queries and mutations in the simple and readable way.
165 lines (129 loc) • 6.14 kB
Markdown
# react-apollo-graphql
[](https://www.npmjs.com/package/react-apollo-graphql)
[](https://circleci.com/gh/michalkvasnicak/react-apollo-graphql/tree/master)



This is opinionated replacement for `graphql` decorator from `react-apollo` package.
`npm install --save react-apollo-graphql`
It provides:
* simple error handling on the component level
* readable passing of queries' results to your component
* typed props and render props using flow type
* server side render
## Usage
### Using `<ApolloProvider />` from `react-apollo`
```js
import GraphQL from 'react-apollo-graphql';
import ApolloClient from 'apollo-client';
import ApolloProvider from 'react-apollo';
<ApolloProvider client={new ApolloClient(...)}>
<GraphQL render={(queries, mutations, props) => <div />} />
</ApolloProvider>
```
### Passing `ApolloClient` directly
```js
import GraphQL from 'react-apollo-graphql';
import ApolloClient from 'apollo-client';
<GraphQL client={new ApolloClient(...)} render={(queries, mutations, props) => <div />} />
```
### Queries
In order to use define and use queries, one has to initialize them.
```js
// @flow
import type { QueryInitializerOptions } from 'react-apollo-graphql';
import type { ApolloClient, ObservableQuery } from 'react-apollo-graphql/lib/types';
const queries = {
// queryA will be resolved only once
queryA: (
client: ApolloClient,
props: Object
): ObservableQuery<{ id: number }> => client.watchQuery({
query: gql`{ id }`,
}),
// queryB will be resolved everytime the relevant props change
queryB: (
client: ApolloClient,
props: Object,
options: QueryInitializerOptions
): ObservableQuery<{ name: string }> => {
// add our function which will be called on every props change
options.hasVariablesChanged((currentProps, nextProps) => {
if (currentProps.name === nextProps.name) {
return false;
}
return { name: nextProps.name };
});
return client.watchQuery({
query: gql`query test($name: String!) { id(name: $name)}`,
variables: { name: props.name },
});
}
};
<GraphQL
queries={queries}
render={(initializedQueries) => {
console.log(initializeQueries.queryA.data);
console.log(initializeQueries.queryA.loading);
console.log(initializeQueries.queryA.error);
console.log(initializeQueries.queryA.networkStatus);
console.log(initializeQueries.queryA.partial);
}}
/>
```
### Mutations
In order to define and use mutations, one has to provided initializers. Initializers are called on every render so you have current `props` available in the initializers.
```js
// @flow
import type { ApolloClient, QueryResult } from 'react-apollo-graphql/lib/types';
const mutations = {
registerUser: (
client: ApolloClient,
props: Object
) => (): Promise<QueryResult<{ registerUser: boolean }>> => client.mutate({
mutation: gql`mutation registerUser($email: String!) { registerUser(email: $email) }`,
variables: {
email: props.email,
},
}),
};
<GraphQL
email="test@test.com"
mutations={mutations}
render={(queries, mutations, props) => {
mutations.registerUser(props.email).then(
(data) => console.log(data.registerUser),
e => console.error(e),
);
}}
/>
```
## API
### ApolloClient
* apollo client is provided from `apollo-client` package. See [documentation](http://dev.apollodata.com/core/apollo-client-api.html#apollo-client).
### QueryInitializerOptions
```js
// @flow
export type QueryInitializerOptions = {
// sets function to determine if there is a relevant change in props to compute new variables
// returns false if there is no change in props used for variables
// or returns new variables for query.setVariables()
hasVariablesChanged: (
(currentProps: Object, nextProps: Object) => boolean | { [key: string]: any },
) => void,
};
```
### `<GraphQL queries?={Queries} mutations?={Mutations} render={RenderFunction} />`
* `Queries = { [key: string]: (client: ApolloClient, props: Object, options: QueryInitializerOptions) => ObservableQuery<*> }`
* `optional` prop, object with query initializers.
* **each initializer will be initialized with apollo client and props passed to initializer on component mount**
* each initializer has to return `ObservableQuery` (this means that it has to call the [`client.watchQuery() method`](http://dev.apollodata.com/core/apollo-client-api.html#ApolloClient\.watchQuery))
* `Mutations = { [key: string]: (client: ApolloClient, props: Object) => () => Promise<QueryResult<*>>}`
* `optional` prop, object with mutation initializers
* **each initializer will be initialized with apollo client and props passed to the initializer on each render (on mount and every update)**
* each initializer has to return `() => Promise<QueryResult<*>>` (this means that it has to call the [`client.mutate() method`](http://dev.apollodata.com/core/apollo-client-api.html#ApolloClient\.mutate))
* `RenderFunction = (queries: InitializedQueries, mutations: InitializedMutations, props) => React$Element<any>`
* called on mount and updates
* `queries` arg: result of each query initializer passed to the `queries` prop on `<GraphQL />` component will be mapped to it's result
* `mutations` arg: each mutation initializer from the `mutations` prop passed to the `<GraphQL />` component will be called on render and the result will be passed under the same `key` to the `mutations` arg of render function.
* `props` arg: current props passed to `<GraphQL />` component