Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge React Apollo hooks into Apollo Client #5357

Merged
merged 29 commits into from
Sep 24, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2c03a0f
Remove specific test matching
hwillson Sep 16, 2019
eca59fe
Dependency updates (peer/dep/devDep) in preparation of RA merge
hwillson Sep 16, 2019
d0eca93
Modernize `OperationVariables` using `Record`
hwillson Sep 16, 2019
c5d872b
TS config changes in preparation of React Apollo being merged in
hwillson Sep 16, 2019
191065c
Bring in React Apollo source
hwillson Sep 16, 2019
d6ef803
Re-export React functionality
hwillson Sep 16, 2019
0f962e0
Typing changes to clear implicit any type errors
hwillson Sep 16, 2019
2e2cb07
Add new global dep exemptions for rollup bundling
hwillson Sep 16, 2019
2418a46
Bundlesize increase to accommodate React code
hwillson Sep 16, 2019
5a102b2
Update all React tests to use async instead of done callbacks
hwillson Sep 17, 2019
6ebacef
Create a new testing bundle
hwillson Sep 19, 2019
a241e09
Remove duplicated `MutationFetchResult`
hwillson Sep 19, 2019
dcf1602
Revert "Create a new testing bundle"
hwillson Sep 21, 2019
0f96dff
Stop building UMD bundles
hwillson Sep 21, 2019
ceedde9
Rollup bundling changes
hwillson Sep 21, 2019
4ecd8e1
Be explicit about root named React exports
hwillson Sep 21, 2019
87c410b
Doc updates to reflect new Apollo Client React API
hwillson Sep 23, 2019
08a2b1e
Merge branch 'release-3.0' into hello-react-apollo
hwillson Sep 23, 2019
68195a9
Pin optimism to 0.11.1
hwillson Sep 23, 2019
c3283dc
Fix TS source links; Exclude API from link checker
hwillson Sep 23, 2019
378bef0
Update all docs deps
hwillson Sep 23, 2019
a36780d
Update fetchOptions to point to new location
hwillson Sep 23, 2019
e6e268c
Revert "Pin optimism to 0.11.1"
benjamn Sep 23, 2019
7ee82b5
`react-dom` no longer needs to be a peer dep
hwillson Sep 23, 2019
b6ab68d
Remove unnecessary `await`s in tests
hwillson Sep 23, 2019
f973610
.npmignore is no longer necessary
hwillson Sep 24, 2019
ef6db11
Change compiled source location from "lib" to "dist"
hwillson Sep 24, 2019
4c7af4e
Adjust publish process to use "dist" as the project root
hwillson Sep 24, 2019
d7db78e
Copy LICENSE into dist during predeploy
hwillson Sep 24, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions docs/gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,13 @@ module.exports = {
'recipes/meteor',
'recipes/recompose',
],
'API Reference': [
'api/apollo-client',
'Apollo Client API': [
'api/core',
'api/react-hooks',
'api/react-ssr',
'api/react-testing',
'api/react-ssr',
'api/react-components',
'api/react-hoc',
'api/react-common',
'api/react-hoc'
],
},
},
Expand Down
4 changes: 2 additions & 2 deletions docs/source/advanced/subscriptions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ Now, queries and mutations will go over HTTP as normal, but subscriptions will b

## useSubscription Hook

The easiest way to bring live data to your UI is by using React Apollo's `useSubscription` Hook. This lets you render the stream of data from your service directly within your render function of your component! One thing to note, subscriptions are just listeners, they don't request any data when first connected, but only open up a connection to get new data. Binding live data to your UI is as easy as this:
The easiest way to bring live data to your UI is by using Apollo Client's `useSubscription` Hook. This lets you render the stream of data from your service directly within your render function of your component! One thing to note, subscriptions are just listeners, they don't request any data when first connected, but only open up a connection to get new data. Binding live data to your UI is as easy as this:

<MultiCodeBlock>
<div data-language="Hooks (JavaScript)">
Expand Down Expand Up @@ -199,7 +199,7 @@ With GraphQL subscriptions your client will be alerted on push from the server a

With `subscribeToMore`, you can easily do the latter.

`subscribeToMore` is a function available on every query result in React Apollo. It works just like [`fetchMore`](/advanced/caching/#incremental-loading-fetchmore), except that the update function gets called every time the subscription returns, instead of only once.
`subscribeToMore` is a function available on every query result, made using Apollo Client's React integration. It works just like [`fetchMore`](/advanced/caching/#incremental-loading-fetchmore), except that the update function gets called every time the subscription returns, instead of only once.

Here is a regular query:

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: class ApolloClient
title: Core
description: Apollo Client core API reference
order: 11
---

Expand Down
35 changes: 0 additions & 35 deletions docs/source/api/react-common.mdx

This file was deleted.

11 changes: 4 additions & 7 deletions docs/source/api/react-components.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: '@apollo/react-components'
description: API reference
title: 'React - Components (DEPRECATED)'
description: Deprecated React Apollo render prop component API
---

import QueryOptions from '../../shared/query-options.mdx';
Expand All @@ -9,7 +9,8 @@ import MutationOptions from '../../shared/mutation-options.mdx';
import MutationResult from '../../shared/mutation-result.mdx';
import SubscriptionOptions from '../../shared/subscription-options.mdx';
import SubscriptionResult from '../../shared/subscription-result.mdx';
import ApolloProvider from '../../shared/apollo-provider.mdx';

> **NOTE:** React Apollo's render prop components have been deprecated. They will continue to receive bug fixes until March 2020, after which they will no longer be maintained by Apollo.

## Installation

Expand Down Expand Up @@ -56,7 +57,3 @@ The Subscription component accepts the following props. Only `subscription` is *
The render prop function that you pass to the `children` prop of `Subscription` is called with an object that has the following properties.

<SubscriptionResult />

## `ApolloProvider`

<ApolloProvider />
16 changes: 7 additions & 9 deletions docs/source/api/react-hoc.mdx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
---
title: '@apollo/react-hoc'
description: API reference
title: 'React - HOC (DEPRECATED)'
description: Deprecated React Apollo HOC API
---

import ApolloProvider from '../../shared/apollo-provider.mdx';

> **NOTE:** React Apollo's higher order components have been deprecated. They will continue to receive bug fixes until March 2020, after which they will no longer be maintained by Apollo.

## Installation

```
Expand Down Expand Up @@ -55,7 +57,7 @@ const TodoAppWithData = withTodoAppQuery(TodoApp);
export default TodoAppWithData;
```

The `graphql()` function will only be able to provide access to your GraphQL data if there is a [`<ApolloProvider/>`](/api/react-common/#apolloprovider) component higher up in your tree to provide an [`ApolloClient`](/api/apollo-client/) instance that will be used to fetch your data.
The `graphql()` function will only be able to provide access to your GraphQL data if there is a [`<ApolloProvider/>`](/api/react-hooks/#apolloprovider) component higher up in your tree to provide an [`ApolloClient`](/api/core/) instance that will be used to fetch your data.

The behavior of your component enhanced with the `graphql()` function will be different depending on if your GraphQL operation is a [query](/essentials/queries/), a [mutation](/essentials/mutations/), or a [subscription](/advanced/subscriptions/). Go to the appropriate API documentation for more information about the functionality and available options for each type.

Expand Down Expand Up @@ -1068,11 +1070,11 @@ export default graphql(
import { withApollo } from '@apollo/react-hoc';
```

A simple enhancer which provides direct access to your [`ApolloClient`](/api/apollo-client/) instance. This is useful if you want to do custom logic with Apollo. Such as calling one-off queries. By calling this function with the component you want to enhance, `withApollo()` will create a new component which passes in an instance of `ApolloClient` as a `client` prop.
A simple enhancer which provides direct access to your [`ApolloClient`](/api/core/) instance. This is useful if you want to do custom logic with Apollo. Such as calling one-off queries. By calling this function with the component you want to enhance, `withApollo()` will create a new component which passes in an instance of `ApolloClient` as a `client` prop.

If you are wondering when to use `withApollo()` and when to use [`graphql()`](#graphqlquery-configcomponent) the answer is that most of the time you will want to use `graphql()`. `graphql()` provides many of the advanced features you need to work with your GraphQL data. You should only use `withApollo()` if you want the GraphQL client without any of the other features.

This will only be able to provide access to your client if there is an [`<ApolloProvider/>`](/api/react-common/#apolloprovider) component higher up in your tree to actually provide the client.
This will only be able to provide access to your client if there is an [`<ApolloProvider/>`](/api/react-hooks/#apolloprovider) component higher up in your tree to actually provide the client.

**Example:**

Expand All @@ -1083,7 +1085,3 @@ function MyComponent({ client }) {

export default withApollo(MyComponent);
```

### `ApolloProvider`

<ApolloProvider />
41 changes: 29 additions & 12 deletions docs/source/api/react-hooks.mdx
Original file line number Diff line number Diff line change
@@ -1,28 +1,47 @@
---
title: '@apollo/react-hooks'
description: API reference
title: React - Hooks
description: Apollo Client React API reference
---

import ApolloProvider from '../../shared/apollo-provider.mdx';
import QueryOptions from '../../shared/query-options.mdx';
import QueryResult from '../../shared/query-result.mdx';
import MutationOptions from '../../shared/mutation-options.mdx';
import MutationResult from '../../shared/mutation-result.mdx';
import SubscriptionOptions from '../../shared/subscription-options.mdx';
import SubscriptionResult from '../../shared/subscription-result.mdx';
import ApolloProvider from '../../shared/subscription-result.mdx';

## Installation

```
npm install @apollo/react-hooks
Apollo Client >= 3 includes React hooks functionality out of the box. You don't need to install any additional packages.

## `ApolloProvider`

<ApolloProvider />

## `ApolloConsumer`

One way to access the configured Apollo Client instance directly is to create an `ApolloConsumer` component and provide a render prop function as its child. The render prop function will be called with your `ApolloClient` instance as its only argument. You can think of the `ApolloConsumer` component as similar to the `Consumer` component from the [React Context API](https://reactjs.org/docs/context.html).

### Example

```jsx
import React from 'react';
import { ApolloConsumer } from '@apollo/client';

const WithApolloClient = () => (
<ApolloConsumer>
{client => 'We have access to the client!' /* do stuff here */}
</ApolloConsumer>
);
```

## `useQuery`

### Example

```jsx
import { useQuery } from '@apollo/react-hooks';
import { useQuery } from '@apollo/client';
import gql from 'graphql-tag';

const GET_GREETING = gql`
Expand Down Expand Up @@ -74,7 +93,7 @@ function useQuery<TData = any, TVariables = OperationVariables>(
### Example

```jsx
import { useLazyQuery } from "@apollo/react-hooks";
import { useLazyQuery } from "@apollo/client";
import gql from "graphql-tag";

const GET_GREETING = gql`
Expand Down Expand Up @@ -141,7 +160,7 @@ function useLazyQuery<TData = any, TVariables = OperationVariables>(
### Example

```jsx
import { useMutation } from '@apollo/react-hooks';
import { useMutation } from '@apollo/client';
import gql from 'graphql-tag';

const ADD_TODO = gql`
Expand Down Expand Up @@ -265,6 +284,8 @@ function useSubscription<TData = any, TVariables = OperationVariables>(
### Example

```jsx
import { useApolloClient } from '@apollo/client';

function SomeComponent() {
const client = useApolloClient();
// `client` is now set to the `ApolloClient` instance being used by the
Expand All @@ -283,7 +304,3 @@ function useApolloClient(): ApolloClient<object> {}
| Param | Type | Description |
| ---------------------- | -------------------------- | ---------------------------------------------------------- |
| Apollo Client instance | ApolloClient&lt;object&gt; | The `ApolloClient` instance being used by the application. |

### `ApolloProvider`

<ApolloProvider />
4 changes: 2 additions & 2 deletions docs/source/api/react-ssr.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "@apollo/react-ssr"
description: API reference
title: React - SSR
description: Apollo Client React server side rendering API
---

## Installation
Expand Down
12 changes: 5 additions & 7 deletions docs/source/api/react-testing.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
---
title: "@apollo/react-testing"
description: API reference
title: React - Testing
description: Apollo Client React testing API
---

## Installation

```
npm install @apollo/react-testing
```
Apollo Client >= 3 includes React testing utilities out of the box. You don't need to install any additional packages.

## `MockedProvider`

```js
import { MockedProvider } from "@apollo/react-testing";
import { MockedProvider } from "@apollo/client/lib/react/testing";
```

The `MockedProvider` is a test-utility that allows you to create a mocked version of the [`ApolloProvider`](/api/react-common/#apolloprovider) that doesn't send out network requests to your API, but rather allows you to specify the exact response payload for a given request.
The `MockedProvider` is a test-utility that allows you to create a mocked version of the [`ApolloProvider`](/api/react-hooks/#apolloprovider) that doesn't send out network requests to your API, but rather allows you to specify the exact response payload for a given request.

The `<MockedProvider />` component takes the following props:

Expand Down
2 changes: 1 addition & 1 deletion docs/source/essentials/get-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,4 @@ Now that you've learned how to fetch data with Apollo Client, you're ready to di

- [Queries](/essentials/queries/): Learn how to fetch queries with arguments and dive deeper into configuration options. For a full list of options, check out the API reference for `useQuery`.
- [Mutations](/essentials/mutations/): Learn how to update data with mutations and when you'll need to update the Apollo cache. For a full list of options, check out the API reference for `useMutation` components.
- [Apollo Client API](/api/apollo-client/): Sometimes, you'll need to access the client directly like we did in our plain JavaScript example above. Visit the API reference for a full list of options.
- [Apollo Client API](/api/core/): Sometimes, you'll need to access the client directly like we did in our plain JavaScript example above. Visit the API reference for a full list of options.
8 changes: 4 additions & 4 deletions docs/source/essentials/local-state.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ cache.writeData({
});
```

Sometimes you may need to [reset the store](/api/apollo-client/#ApolloClient.resetStore) in your application, when a user logs out for example. If you call `client.resetStore` anywhere in your application, you will likely want to initialize your cache again. You can do this using the `client.onResetStore` method to register a callback that will call `cache.writeData` again.
Sometimes you may need to [reset the store](/api/core/#ApolloClient.resetStore) in your application, when a user logs out for example. If you call `client.resetStore` anywhere in your application, you will likely want to initialize your cache again. You can do this using the `client.onResetStore` method to register a callback that will call `cache.writeData` again.

```js
import { ApolloClient, InMemoryCache } from '@apollo/client';
Expand Down Expand Up @@ -717,15 +717,15 @@ ReactDOM.render(
</div>
</MultiCodeBlock>

In the above example, we first prep the cache using `cache.writeData` to store a value for the `isLoggedIn` field. We then run the `IS_LOGGED_IN` query via a React Apollo `useQuery` hook, which includes an `@client` directive. When Apollo Client executes the `IS_LOGGED_IN` query, it first looks for a local resolver that can be used to handle the `@client` field. When it can't find one, it falls back on trying to pull the specified field out of the cache. So in this case, the `data` value returned by the `useQuery` hook has a `isLoggedIn` property available, which includes the `isLoggedIn` result (`!!localStorage.getItem('token')`) pulled directly from the cache.
In the above example, we first prep the cache using `cache.writeData` to store a value for the `isLoggedIn` field. We then run the `IS_LOGGED_IN` query via an Apollo Client `useQuery` hook, which includes an `@client` directive. When Apollo Client executes the `IS_LOGGED_IN` query, it first looks for a local resolver that can be used to handle the `@client` field. When it can't find one, it falls back on trying to pull the specified field out of the cache. So in this case, the `data` value returned by the `useQuery` hook has a `isLoggedIn` property available, which includes the `isLoggedIn` result (`!!localStorage.getItem('token')`) pulled directly from the cache.

> ⚠️ If you want to use Apollo Client's `@client` support to query the cache without using local resolvers, you must pass an empty object into the `ApolloClient` constructor `resolvers` option. Without this Apollo Client will not enable its integrated `@client` support, which means your `@client` based queries will be passed to the Apollo Client link chain. You can find more details about why this is necessary [here](https://github.com/apollographql/apollo-client/pull/4499).

Pulling `@client` field values directly out of the cache isn't quite as flexible as local resolver functions, since local resolvers can perform extra computations before returning a result. Depending on your application's needs however, loading `@client` fields directly from the cache might be a simpler option. Apollo Client doesn't restrict combining both approaches, so feel free to mix and match. If the need arises, you can pull some `@client` values from the cache, and resolve others with local resolvers, all in the same query.

### Working with fetch policies

Before Apollo Client executes a query, one of the first things it does is check to see which [`fetchPolicy`](/api/apollo-client/#ApolloClient.query) it has been configured to use. It does this so it knows where it should attempt to resolve the query from first, either the cache or the network. When running a query, Apollo Client treats `@client` based local resolvers just like it does remote resolvers, in that it will adhere to its defined `fetchPolicy` to know where to attempt to pull data from first. When working with local resolvers, it's important to understand how fetch policies impact the running of resolver functions, since by default local resolver functions are not run on every request. This is because the result of running a local resolver is cached with the rest of the query result, and pulled from the cache on the next request. Let's look at an example:
Before Apollo Client executes a query, one of the first things it does is check to see which [`fetchPolicy`](/api/core/#ApolloClient.query) it has been configured to use. It does this so it knows where it should attempt to resolve the query from first, either the cache or the network. When running a query, Apollo Client treats `@client` based local resolvers just like it does remote resolvers, in that it will adhere to its defined `fetchPolicy` to know where to attempt to pull data from first. When working with local resolvers, it's important to understand how fetch policies impact the running of resolver functions, since by default local resolver functions are not run on every request. This is because the result of running a local resolver is cached with the rest of the query result, and pulled from the cache on the next request. Let's look at an example:

<MultiCodeBlock>
<div data-language="Hooks (JavaScript)">
Expand Down Expand Up @@ -818,7 +818,7 @@ export default function Launch({ launchId }) {
</div>
</MultiCodeBlock>

In the above example we're using a React Apollo `useQuery` hook to run the `GET_LAUNCH_DETAILS` query. The `@client` based `isInCart` field is configured to pull its data from the following resolver:
In the above example we're using an Apollo Client `useQuery` hook to run the `GET_LAUNCH_DETAILS` query. The `@client` based `isInCart` field is configured to pull its data from the following resolver:

```js
import { GET_CART_ITEMS } from './pages/cart';
Expand Down
2 changes: 1 addition & 1 deletion docs/source/essentials/queries.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const GET_DOGS = gql`

```tsx:title=index.js
import gql from 'graphql-tag';
import { Query } from 'react-apollo';
import { Query } from '@apollo/react-components';

const GET_DOGS = gql`
{
Expand Down
Loading