graphql-react
Advanced tools
Comparing version 8.3.0 to 9.0.0
# graphql-react changelog | ||
## 9.0.0 | ||
### Major | ||
- Updated Node.js support from v8.5+ to v8.10+, to match what the [`eslint`](https://npm.im/eslint) dev dependency now supports. This is unlikely to be a breaking change for the published package. | ||
- The `useGraphQL` React hook `loadOnMount`, `loadOnReload`, and `loadOnReset` options now default to `false` instead of `true`. The loading related options are now all opt-in, which is easier to remember and simpler to configure for situations that previously required manual reversal of certain option defaults. It's also safer when working with mutations you don't want to accidentally load. | ||
### Patch | ||
- Updated dependencies. | ||
- Replaced the [`size-limit`](https://npm.im/size-limit) dev dependency with [`@size-limit/preset-small-lib`](https://npm.im/@size-limit/preset-small-lib). | ||
- Fixed the `useGraphQL` enabled option `loadOnReload` causing a load when the global `GraphQL` cache is reloaded even if there was no previously cached data to reload. | ||
- Tweaked the `useGraphQL` option `loadOnReset` documentation. | ||
- Removed `package-lock.json` from `.gitignore` and `.prettierignore` as it’s disabled in `.npmrc` anyway. | ||
- Removed redundant ESLint ignore comments. | ||
- Use GitHub Actions instead of Travis for CI. | ||
- Minor simplification in `useGraphQL` tests. | ||
- Documentation improvements, fixing [#35](https://github.com/jaydenseric/graphql-react/issues/35): | ||
- Updated the project description with better phrasing that includes the bundle size. | ||
- Moved the readme “Apollo comparison” section to the end, and updated the “Bundle impact” subsection for the new Apollo React hooks API. | ||
- Added a basic example of the core API features working together to the “Examples” section, with tips commented. | ||
- Clarified that Opera Mini isn’t supported in the Browserslist queries and readme “Support” section. | ||
- Cleaner readme “API” section table of contents with “See” and “Examples” headings excluded, thanks to [`jsdoc-md` v3.1.0](https://github.com/jaydenseric/jsdoc-md/releases/tag/v3.1.0). | ||
## 8.3.0 | ||
@@ -4,0 +28,0 @@ |
{ | ||
"name": "graphql-react", | ||
"version": "8.3.0", | ||
"description": "A lightweight but powerful GraphQL client for React using modern context and hooks APIs; the first Relay and Apollo alternative with server side rendering.", | ||
"version": "9.0.0", | ||
"description": "A GraphQL client for React using modern context and hooks APIs that is lightweight (< 2.5 KB size limited) but powerful; the first Relay and Apollo alternative with server side rendering.", | ||
"license": "MIT", | ||
@@ -35,5 +35,5 @@ "author": { | ||
"engines": { | ||
"node": ">=8.5" | ||
"node": ">=8.10" | ||
}, | ||
"browserslist": "> 0.5%, not dead, node >= 8.5", | ||
"browserslist": "Node >= 8.10, > 0.5%, not OperaMini all, not dead", | ||
"peerDependencies": { | ||
@@ -44,3 +44,3 @@ "react": "^16.8.0", | ||
"dependencies": { | ||
"@babel/runtime": "^7.5.4", | ||
"@babel/runtime": "^7.5.5", | ||
"extract-files": "^5.0.1", | ||
@@ -53,27 +53,28 @@ "fnv1a": "^1.0.1", | ||
"devDependencies": { | ||
"@babel/cli": "^7.5.0", | ||
"@babel/core": "^7.5.4", | ||
"@babel/plugin-proposal-class-properties": "^7.5.0", | ||
"@babel/plugin-proposal-object-rest-spread": "^7.5.4", | ||
"@babel/plugin-transform-runtime": "^7.5.0", | ||
"@babel/preset-env": "^7.5.4", | ||
"@babel/cli": "^7.5.5", | ||
"@babel/core": "^7.5.5", | ||
"@babel/plugin-proposal-class-properties": "^7.5.5", | ||
"@babel/plugin-proposal-object-rest-spread": "^7.5.5", | ||
"@babel/plugin-transform-runtime": "^7.5.5", | ||
"@babel/preset-env": "^7.5.5", | ||
"@babel/preset-react": "^7.0.0", | ||
"@size-limit/preset-small-lib": "^2.2.1", | ||
"babel-eslint": "^10.0.2", | ||
"babel-plugin-transform-replace-object-assign": "^2.0.0", | ||
"cross-fetch": "^3.0.4", | ||
"eslint": "^6.0.1", | ||
"eslint-config-env": "^8.0.0", | ||
"eslint": "^6.1.0", | ||
"eslint-config-env": "^11.0.0", | ||
"eslint-config-prettier": "^6.0.0", | ||
"eslint-plugin-import": "^2.18.0", | ||
"eslint-plugin-import-order-alphabetical": "^0.0.2", | ||
"eslint-plugin-jsdoc": "^15.5.1", | ||
"eslint-plugin-node": "^9.1.0", | ||
"eslint-plugin-import": "^2.18.2", | ||
"eslint-plugin-import-order-alphabetical": "^1.0.0", | ||
"eslint-plugin-jsdoc": "^18.1.4", | ||
"eslint-plugin-node": "^10.0.0", | ||
"eslint-plugin-prettier": "^3.1.0", | ||
"eslint-plugin-react": "^7.14.2", | ||
"eslint-plugin-react-hooks": "^1.6.1", | ||
"eslint-plugin-react": "^7.14.3", | ||
"eslint-plugin-react-hooks": "^2.3.0", | ||
"formdata-node": "^1.8.0", | ||
"graphql": "^14.4.2", | ||
"graphql-api-koa": "^2.0.0", | ||
"husky": "^3.0.0", | ||
"jsdoc-md": "^3.0.0", | ||
"husky": "^3.0.1", | ||
"jsdoc-md": "^4.0.1", | ||
"koa": "^2.7.0", | ||
@@ -86,4 +87,3 @@ "koa-bodyparser": "^4.2.1", | ||
"react-test-renderer": "^16.8.6", | ||
"size-limit": "^1.3.7", | ||
"tap": "^14.4.1" | ||
"tap": "^14.10.1" | ||
}, | ||
@@ -90,0 +90,0 @@ "scripts": { |
409
readme.md
@@ -5,7 +5,6 @@ ![graphql-react logo](https://cdn.jsdelivr.net/gh/jaydenseric/graphql-react@0.1.0/graphql-react-logo.svg) | ||
[![npm version](https://badgen.net/npm/v/graphql-react)](https://npm.im/graphql-react) [![Build status](https://travis-ci.org/jaydenseric/graphql-react.svg?branch=master)](https://travis-ci.org/jaydenseric/graphql-react) | ||
[![npm version](https://badgen.net/npm/v/graphql-react)](https://npm.im/graphql-react) [![CI status](https://github.com/jaydenseric/graphql-react/workflows/CI/badge.svg)](https://github.com/jaydenseric/graphql-react/actions) | ||
A lightweight but powerful GraphQL client for React using modern [context](https://reactjs.org/docs/context) and [hooks](https://reactjs.org/docs/hooks-intro) APIs; the first [Relay](https://facebook.github.io/relay) and [Apollo](https://apollographql.com/docs/react) alternative with server side rendering. | ||
A [GraphQL](https://graphql.org) client for [React](https://reactjs.org) using modern [context](https://reactjs.org/docs/context) and [hooks](https://reactjs.org/docs/hooks-intro) APIs that is lightweight (< 2.5 KB [size limited](https://github.com/ai/size-limit)) but powerful; the first [Relay](https://facebook.github.io/relay) and [Apollo](https://apollographql.com/docs/react) alternative with server side rendering. | ||
- [Apollo comparison](#apollo-comparison) | ||
- [Setup](#setup) | ||
@@ -16,150 +15,4 @@ - [Usage](#usage) | ||
- [API](#api) | ||
- [Apollo comparison](#apollo-comparison) | ||
## Apollo comparison | ||
### Bundle impact | ||
#### graphql-react | ||
A < 2.5 KB bundle impact is guaranteed by [`size-limit`](https://npm.im/size-limit) tests. The impact is smaller than the bundle size badge suggests as the internal [`object-assign`](https://npm.im/object-assign) dependency is shared with [`react`](https://npm.im/react). | ||
| Dependency | Install size | Bundle size | | ||
| --- | --- | --- | | ||
| [`graphql-react`](https://npm.im/graphql-react) | [![graphql-react install size](https://badgen.net/packagephobia/install/graphql-react)](https://packagephobia.now.sh/result?p=graphql-react) | [![graphql-react minzipped size](https://badgen.net/bundlephobia/minzip/graphql-react)](https://bundlephobia.com/result?p=graphql-react) | | ||
[Tree shaking](https://developer.mozilla.org/docs/Glossary/Tree_shaking) bundlers will eliminate unused exports (perhaps [`reportCacheErrors`](#function-reportcacheerrors)). | ||
#### Apollo | ||
Several dependencies must be installed for a minimal Apollo project. | ||
| Dependency | Install size | Bundle size | | ||
| --- | --- | --- | | ||
| [`apollo-boost`](https://npm.im/apollo-boost) | [![apollo-boost install size](https://badgen.net/packagephobia/install/apollo-boost)](https://packagephobia.now.sh/result?p=apollo-boost) | [![apollo-boost minzipped size](https://badgen.net/bundlephobia/minzip/apollo-boost)](https://bundlephobia.com/result?p=apollo-boost) | | ||
| [`react-apollo`](https://npm.im/react-apollo) | [![react-apollo install size](https://badgen.net/packagephobia/install/react-apollo)](https://packagephobia.now.sh/result?p=react-apollo) | [![react-apollo minzipped size](https://badgen.net/bundlephobia/minzip/react-apollo)](https://bundlephobia.com/result?p=react-apollo) | | ||
| [`graphql-tag`](https://npm.im/graphql-tag) | [![graphql-tag install size](https://badgen.net/packagephobia/install/graphql-tag)](https://packagephobia.now.sh/result?p=graphql-tag) | [![graphql-tag minzipped size](https://badgen.net/bundlephobia/minzip/graphql-tag)](https://bundlephobia.com/result?p=graphql-tag) | | ||
| [`graphql`](https://npm.im/graphql) | [![graphql install size](https://badgen.net/packagephobia/install/graphql)](https://packagephobia.now.sh/result?p=graphql) | [![graphql minzipped size](https://badgen.net/bundlephobia/minzip/graphql)](https://bundlephobia.com/result?p=graphql) | | ||
[Tree shaking](https://developer.mozilla.org/docs/Glossary/Tree_shaking) bundlers will eliminate unused [`graphql`](https://npm.im/graphql) exports. | ||
In addition, [fragment matcher](https://www.apollographql.com/docs/react/advanced/fragments#fragment-matcher) config impacts bundle size relative to the number and complexity of schema unions and interfaces; see [**_Cache strategy_**](#cache-strategy). | ||
### Native ESM | ||
#### graphql-react | ||
Supports native ESM via `.mjs` files for Node.js in [`--experimental-modules`](https://nodejs.org/api/esm.html#esm_enabling) mode and [tree shaking](https://developer.mozilla.org/docs/Glossary/Tree_shaking) bundlers like [webpack](https://webpack.js.org). For legacy environments CJS is provided via `.js` files. | ||
#### Apollo | ||
No support for native ESM, although they do provide faux ESM via package `module` fields for [tree shaking](https://developer.mozilla.org/docs/Glossary/Tree_shaking) bundlers like [webpack](https://webpack.js.org). | ||
### Writing queries | ||
#### graphql-react | ||
Uses template strings: | ||
```js | ||
const QUERY = /* GraphQL */ ` | ||
{ | ||
viewer { | ||
id | ||
} | ||
} | ||
` | ||
``` | ||
The optional `/* GraphQL */` comment signals the syntax for highlighters and linters. | ||
#### Apollo | ||
Uses template strings tagged with `gql` from [`graphql-tag`](https://npm.im/graphql-tag): | ||
```js | ||
import gql from 'graphql-tag' | ||
const QUERY = gql` | ||
{ | ||
viewer { | ||
id | ||
} | ||
} | ||
` | ||
``` | ||
### Cache strategy | ||
#### graphql-react | ||
The [`GraphQL`](#class-graphql) client has no GraphQL API specific config; [`fetch`](https://developer.mozilla.org/docs/Web/API/Fetch_API) options are determined on demand at the component level. Multiple GraphQL APIs can be queried! | ||
GraphQL operations are cached under hashes of their [`fetch`](https://developer.mozilla.org/docs/Web/API/Fetch_API) options. Multiple operations with the same hash share the same loading status and cache value. | ||
[`fetch`](https://developer.mozilla.org/docs/Web/API/Fetch_API), HTTP, parse and GraphQL errors can be cached, and therefore server side rendered and transported to the client for hydration and initial render. | ||
#### Apollo | ||
Apollo Client is configured for one GraphQL API per app. | ||
GraphQL operation data is deconstructed based upon `id` and `__typename` fields into a “[normalized](https://apollographql.com/docs/react/advanced/caching#normalization)” cache. These fields must be queried even if they aren’t used in components. | ||
[Errors aren’t cached](https://github.com/apollographql/apollo-client/issues/3897#issuecomment-432982170), and therefore can’t be server side rendered and transported to the client for hydration and initial render. | ||
Apollo Client must be configured with schema knowledge extracted at build time for a “[fragment matcher](https://apollographql.com/docs/react/advanced/fragments#fragment-matcher)” to cache fragments on unions and interfaces properly. It’s challenging to reconfigure and redeploy clients whenever the GraphQL schema updates. Also, the config increases the client bundle size; see [**_Bundle impact_**](#bundle-impact). | ||
### Stale cache | ||
#### graphql-react | ||
By default, cache is refreshed for mounting components. | ||
GraphQL operations can optionally refresh all cache except their own fresh cache; handy for mutations. | ||
#### Apollo | ||
By default, cache isn’t refreshed for mounting components. | ||
GraphQL mutations only update the cache with the contents of their payload. The prescribed approach is to try to manually update other normalized cache after mutations using complicated and often buggy APIs. Resetting all cache is possible, but it also wipes the result of the last operation. | ||
### File uploads | ||
#### graphql-react | ||
Out of the box file uploads compliant with the [GraphQL multipart request spec](https://github.com/jaydenseric/graphql-multipart-request-spec) (authored by [@jaydenseric](https://github.com/jaydenseric)) which is supported by popular GraphQL servers including [Apollo Server](https://apollographql.com/docs/apollo-server). File input values can be used as query or mutation arguments. | ||
#### Apollo | ||
Supports file uploads if you drop [`apollo-boost`](https://npm.im/apollo-boost) and manually setup Apollo Client with [`apollo-upload-client`](https://npm.im/apollo-upload-client) (also by [@jaydenseric](https://github.com/jaydenseric)). | ||
### Subscriptions | ||
#### graphql-react | ||
Not supported yet. | ||
#### Apollo | ||
Supported. | ||
### TypeScript | ||
#### graphql-react | ||
Written in ECMAScript; no types are exported. | ||
#### Apollo | ||
Written in TypeScript; types are exported. | ||
### Next.js integration | ||
#### graphql-react | ||
Has [an official example](https://github.com/zeit/next.js/tree/canary/examples/with-graphql-react) using [`next-graphql-react`](https://npm.im/next-graphql-react), which provides easy an easy to install [`App`](https://nextjs.org/docs/#custom-app) decorator and [plugin](https://nextjs.org/docs/#custom-configuration) to enable server side rendered GraphQL queries. | ||
#### Apollo | ||
Has [an official example](https://github.com/zeit/next.js/tree/canary/examples/with-apollo), but it consists of over 100 lines of complicated copy-paste boilerplate code across multiple files. | ||
## Setup | ||
@@ -192,6 +45,69 @@ | ||
Here is a basic example that displays a Pokemon image, with tips commented: | ||
```jsx | ||
import { GraphQL, GraphQLProvider, useGraphQL } from 'graphql-react' | ||
// Zero config GraphQL client that manages the cache. | ||
const graphql = new GraphQL() | ||
const PokemonImage = ({ name }) => { | ||
// The useGraphQL hook can be used just the same for queries or mutations. | ||
const { loading, cacheValue = {} } = useGraphQL({ | ||
// Any GraphQL API can be queried in components, where fetch options for | ||
// the URL, auth headers, etc. are specified. To avoid repetition it’s a | ||
// good idea to import the fetch options override functions for the APIs | ||
// your app uses from a central module. The default fetch options received | ||
// by the override function are tailored to the operation; typically the | ||
// body is JSON but if there are files in the variables it will be a | ||
// FormData instance for a GraphQL multipart request. | ||
fetchOptionsOverride(options) { | ||
options.url = 'https://graphql-pokemon.now.sh' | ||
}, | ||
// The operation typically contains `query` and sometimes `variables`, but | ||
// additional properties can be used; all are JSON encoded and sent to the | ||
// GraphQL server in the fetch request body. | ||
operation: { | ||
query: `{ pokemon(name: "${name}") { image } }` | ||
}, | ||
// Load the query whenever the component mounts. This is desirable for | ||
// queries to display content, but not for on demand situations like | ||
// pagination view more buttons or forms that submit mutations. | ||
loadOnMount: true, | ||
// Reload the query whenever a global cache reload is signaled. | ||
loadOnReload: true, | ||
// Reload the query whenever the global cache is reset. Resets immediately | ||
// delete the cache and are mostly only used when logging out the user. | ||
loadOnReset: true | ||
}) | ||
return cacheValue.data ? ( | ||
<img src={cacheValue.data.pokemon.image} alt={name} /> | ||
) : loading ? ( | ||
// Data is often reloaded, so don’t assume loading indicates no data. | ||
'Loading…' | ||
) : ( | ||
// Detailed error info is available in the `cacheValue` properties | ||
// `fetchError`, `httpError`, `parseError` and `graphQLErrors`. A combination | ||
// of errors is possible, and an error doesn’t necessarily mean data is | ||
// unavailable. | ||
'Error!' | ||
) | ||
} | ||
const App = () => ( | ||
<GraphQLProvider graphql={graphql}> | ||
<PokemonImage name="pikachu" /> | ||
</GraphQLProvider> | ||
) | ||
``` | ||
## Support | ||
- Node.js v8.5+ | ||
- Browsers [`> 0.5%, not dead`](https://browserl.ist/?q=%3E+0.5%25%2C+not+dead) | ||
- Node.js v8.10+ | ||
- Browsers [`> 0.5%, not OperaMini all, not dead`](https://browserl.ist/?q=%3E+0.5%25%2C+not+OperaMini+all%2C+not+dead) | ||
@@ -209,44 +125,22 @@ Consider polyfilling: | ||
- [class GraphQL](#class-graphql) | ||
- [See](#see) | ||
- [Examples](#examples) | ||
- [GraphQL instance method off](#graphql-instance-method-off) | ||
- [GraphQL instance method on](#graphql-instance-method-on) | ||
- [See](#see-1) | ||
- [GraphQL instance method operate](#graphql-instance-method-operate) | ||
- [GraphQL instance method reload](#graphql-instance-method-reload) | ||
- [Examples](#examples-1) | ||
- [GraphQL instance method reset](#graphql-instance-method-reset) | ||
- [Examples](#examples-2) | ||
- [GraphQL instance property cache](#graphql-instance-property-cache) | ||
- [Examples](#examples-3) | ||
- [GraphQL instance property operations](#graphql-instance-property-operations) | ||
- [function GraphQLProvider](#function-graphqlprovider) | ||
- [See](#see-2) | ||
- [Examples](#examples-4) | ||
- [function reportCacheErrors](#function-reportcacheerrors) | ||
- [Examples](#examples-5) | ||
- [function ssr](#function-ssr) | ||
- [See](#see-3) | ||
- [Examples](#examples-6) | ||
- [function useGraphQL](#function-usegraphql) | ||
- [See](#see-4) | ||
- [Examples](#examples-7) | ||
- [constant GraphQLContext](#constant-graphqlcontext) | ||
- [See](#see-5) | ||
- [Examples](#examples-8) | ||
- [type GraphQLCache](#type-graphqlcache) | ||
- [See](#see-6) | ||
- [type GraphQLCacheKey](#type-graphqlcachekey) | ||
- [type GraphQLCacheValue](#type-graphqlcachevalue) | ||
- [type GraphQLFetchOptions](#type-graphqlfetchoptions) | ||
- [See](#see-7) | ||
- [type GraphQLFetchOptionsOverride](#type-graphqlfetchoptionsoverride) | ||
- [See](#see-8) | ||
- [Examples](#examples-9) | ||
- [type GraphQLOperation](#type-graphqloperation) | ||
- [See](#see-9) | ||
- [type GraphQLOperationLoading](#type-graphqloperationloading) | ||
- [See](#see-10) | ||
- [type GraphQLOperationStatus](#type-graphqloperationstatus) | ||
- [See](#see-11) | ||
- [type HttpError](#type-httperror) | ||
@@ -261,4 +155,4 @@ - [type ReactNode](#type-reactnode) | ||
| :-- | :-- | :-- | | ||
| `options` | object? = `{}` | Options. | | ||
| `options.cache` | [GraphQLCache](#type-graphqlcache)? = `{}` | Cache to import; usually from a server side render. | | ||
| `options` | object? = {} | Options. | | ||
| `options.cache` | [GraphQLCache](#type-graphqlcache)? = {} | Cache to import; usually from a server side render. | | ||
@@ -449,3 +343,3 @@ #### See | ||
| `node` | [ReactNode](#type-reactnode) | React virtual DOM node. | | ||
| `render` | Function? = `ReactDOMServer.renderToStaticMarkup` | Synchronous React server side render function, defaulting to [`ReactDOMServer.renderToStaticMarkup`](https://reactjs.org/docs/react-dom-server.html#rendertostaticmarkup) as it is more efficient than [`ReactDOMServer.renderToString`](https://reactjs.org/docs/react-dom-server.html#rendertostring). | | ||
| `render` | Function? = ReactDOMServer.renderToStaticMarkup | Synchronous React server side render function, defaulting to [`ReactDOMServer.renderToStaticMarkup`](https://reactjs.org/docs/react-dom-server.html#rendertostaticmarkup) as it is more efficient than [`ReactDOMServer.renderToString`](https://reactjs.org/docs/react-dom-server.html#rendertostring). | | ||
@@ -510,5 +404,5 @@ **Returns:** Promise<string> — Promise resolving the rendered HTML string. | ||
| `options.fetchOptionsOverride` | [GraphQLFetchOptionsOverride](#type-graphqlfetchoptionsoverride)? | Overrides default [`fetch` options](#type-graphqlfetchoptions) for the GraphQL operation. | | ||
| `options.loadOnMount` | boolean? = `true` | Should the operation load when the component mounts. | | ||
| `options.loadOnReload` | boolean? = `true` | Should the operation load when the [`GraphQL`](#class-graphql) `reload` event fires, if the operation was not the one that caused the reload. | | ||
| `options.loadOnReset` | boolean? = `true` | Should the operation load when its [GraphQL cache](#graphql-instance-property-cache) [value](#type-graphqlcachevalue) is reset, if the operation was not the one that caused the reset. | | ||
| `options.loadOnMount` | boolean? = `false` | Should the operation load when the component mounts. | | ||
| `options.loadOnReload` | boolean? = `false` | Should the operation load when the [`GraphQL`](#class-graphql) `reload` event fires and there is a [GraphQL cache](#graphql-instance-property-cache) [value](#type-graphqlcachevalue) to reload, but only if the operation was not the one that caused the reload. | | ||
| `options.loadOnReset` | boolean? = `false` | Should the operation load when the [`GraphQL`](#class-graphql) `reset` event fires and the [GraphQL cache](#graphql-instance-property-cache) [value](#type-graphqlcachevalue) is deleted, but only if the operation was not the one that caused the reset. | | ||
| `options.reloadOnLoad` | boolean? = `false` | Should a [GraphQL reload](#graphql-instance-method-reload) happen after the operation loads, excluding the loaded operation cache. | | ||
@@ -538,3 +432,6 @@ | `options.resetOnLoad` | boolean? = `false` | Should a [GraphQL reset](#graphql-instance-method-reset) happen after the operation loads, excluding the loaded operation cache. | | ||
> query: `{ pokemon(name: "${name}") { image } }` | ||
> } | ||
> }, | ||
> loadOnMount: true, | ||
> loadOnReload: true, | ||
> loadOnReset: true | ||
> }) | ||
@@ -554,4 +451,2 @@ > | ||
> The defaults are suitable for typical query use, as apps tend to have more queries than mutations. | ||
> | ||
> | Situation | `loadOnMount` | `loadOnReload` | `loadOnReset` | `reloadOnLoad` | `resetOnLoad` | | ||
@@ -756,2 +651,148 @@ > | :-- | :-: | :-: | :-: | :-: | :-: | | ||
**Type:** undefined | null | boolean | number | string | React.Element | Array<[ReactNode](#type-reactnode)> | ||
**Type:** `undefined` | `null` | boolean | number | string | React.Element | Array<[ReactNode](#type-reactnode)> | ||
## Apollo comparison | ||
### Bundle impact | ||
#### graphql-react | ||
A < 2.5 KB bundle impact is guaranteed by [Size Limit](https://github.com/ai/size-limit) tests. The impact is smaller than the bundle size badge suggests as the internal [`object-assign`](https://npm.im/object-assign) dependency is shared with [`react`](https://npm.im/react). | ||
| Dependency | Install size | Bundle size | | ||
| --- | --- | --- | | ||
| [`graphql-react`](https://npm.im/graphql-react) | [![graphql-react install size](https://badgen.net/packagephobia/install/graphql-react)](https://packagephobia.now.sh/result?p=graphql-react) | [![graphql-react minzipped size](https://badgen.net/bundlephobia/minzip/graphql-react)](https://bundlephobia.com/result?p=graphql-react) | | ||
[Tree shaking](https://developer.mozilla.org/docs/Glossary/Tree_shaking) bundlers will eliminate unused exports (perhaps [`reportCacheErrors`](#function-reportcacheerrors)). | ||
#### Apollo | ||
Several dependencies must be installed for a minimal Apollo project. | ||
| Dependency | Install size | Bundle size | | ||
| --- | --- | --- | | ||
| [`apollo-boost`](https://npm.im/apollo-boost) | [![apollo-boost install size](https://badgen.net/packagephobia/install/apollo-boost)](https://packagephobia.now.sh/result?p=apollo-boost) | [![apollo-boost minzipped size](https://badgen.net/bundlephobia/minzip/apollo-boost)](https://bundlephobia.com/result?p=apollo-boost) | | ||
| [`@apollo/react-hooks`](https://npm.im/@apollo/react-hooks) | [![@apollo/react-hooks install size](https://badgen.net/packagephobia/install/@apollo/react-hooks)](https://packagephobia.now.sh/result?p=@apollo/react-hooks) | [![@apollo/react-hooks minzipped size](https://badgen.net/bundlephobia/minzip/@apollo/react-hooks)](https://bundlephobia.com/result?p=@apollo/react-hooks) | | ||
| [`graphql`](https://npm.im/graphql) | [![graphql install size](https://badgen.net/packagephobia/install/graphql)](https://packagephobia.now.sh/result?p=graphql) | [![graphql minzipped size](https://badgen.net/bundlephobia/minzip/graphql)](https://bundlephobia.com/result?p=graphql) | | ||
[Tree shaking](https://developer.mozilla.org/docs/Glossary/Tree_shaking) bundlers will eliminate unused [`graphql`](https://npm.im/graphql) exports. | ||
In addition, [fragment matcher](https://www.apollographql.com/docs/react/advanced/fragments#fragment-matcher) config impacts bundle size relative to the number and complexity of schema unions and interfaces; see [**_Cache strategy_**](#cache-strategy). | ||
### Native ESM | ||
#### graphql-react | ||
Supports native ESM via `.mjs` files for Node.js in [`--experimental-modules`](https://nodejs.org/api/esm.html#esm_enabling) mode and [tree shaking](https://developer.mozilla.org/docs/Glossary/Tree_shaking) bundlers like [webpack](https://webpack.js.org). For legacy environments CJS is provided via `.js` files. | ||
#### Apollo | ||
No support for native ESM, although they do provide faux ESM via package `module` fields for [tree shaking](https://developer.mozilla.org/docs/Glossary/Tree_shaking) bundlers like [webpack](https://webpack.js.org). | ||
### Writing queries | ||
#### graphql-react | ||
Uses template strings: | ||
```js | ||
const QUERY = /* GraphQL */ ` | ||
{ | ||
viewer { | ||
id | ||
} | ||
} | ||
` | ||
``` | ||
The optional `/* GraphQL */` comment signals the syntax for highlighters and linters. | ||
#### Apollo | ||
Uses template strings tagged with `gql` from [`graphql-tag`](https://npm.im/graphql-tag): | ||
```js | ||
import gql from 'graphql-tag' | ||
const QUERY = gql` | ||
{ | ||
viewer { | ||
id | ||
} | ||
} | ||
` | ||
``` | ||
### Cache strategy | ||
#### graphql-react | ||
The [`GraphQL`](#class-graphql) client has no GraphQL API specific config; [`fetch`](https://developer.mozilla.org/docs/Web/API/Fetch_API) options are determined on demand at the component level. Multiple GraphQL APIs can be queried! | ||
GraphQL operations are cached under hashes of their [`fetch`](https://developer.mozilla.org/docs/Web/API/Fetch_API) options. Multiple operations with the same hash share the same loading status and cache value. | ||
[`fetch`](https://developer.mozilla.org/docs/Web/API/Fetch_API), HTTP, parse and GraphQL errors can be cached, and therefore server side rendered and transported to the client for hydration and initial render. | ||
#### Apollo | ||
Apollo Client is configured for one GraphQL API per app. | ||
GraphQL operation data is deconstructed based upon `id` and `__typename` fields into a “[normalized](https://apollographql.com/docs/react/advanced/caching#normalization)” cache. These fields must be queried even if they aren’t used in components. | ||
[Errors aren’t cached](https://github.com/apollographql/apollo-client/issues/3897#issuecomment-432982170), and therefore can’t be server side rendered and transported to the client for hydration and initial render. | ||
Apollo Client must be configured with schema knowledge extracted at build time for a “[fragment matcher](https://apollographql.com/docs/react/advanced/fragments#fragment-matcher)” to cache fragments on unions and interfaces properly. It’s challenging to reconfigure and redeploy clients whenever the GraphQL schema updates. Also, the config increases the client bundle size; see [**_Bundle impact_**](#bundle-impact). | ||
### Stale cache | ||
#### graphql-react | ||
By default, cache is refreshed for mounting components. | ||
GraphQL operations can optionally refresh all cache except their own fresh cache; handy for mutations. | ||
#### Apollo | ||
By default, cache isn’t refreshed for mounting components. | ||
GraphQL mutations only update the cache with the contents of their payload. The prescribed approach is to try to manually update other normalized cache after mutations using complicated and often buggy APIs. Resetting all cache is possible, but it also wipes the result of the last operation. | ||
### File uploads | ||
#### graphql-react | ||
Out of the box file uploads compliant with the [GraphQL multipart request spec](https://github.com/jaydenseric/graphql-multipart-request-spec) (authored by [@jaydenseric](https://github.com/jaydenseric)) which is supported by popular GraphQL servers including [Apollo Server](https://apollographql.com/docs/apollo-server). File input values can be used as query or mutation arguments. | ||
#### Apollo | ||
Supports file uploads if you drop [`apollo-boost`](https://npm.im/apollo-boost) and manually setup Apollo Client with [`apollo-upload-client`](https://npm.im/apollo-upload-client) (also by [@jaydenseric](https://github.com/jaydenseric)). | ||
### Subscriptions | ||
#### graphql-react | ||
Not supported yet. | ||
#### Apollo | ||
Supported. | ||
### TypeScript | ||
#### graphql-react | ||
Written in ECMAScript; no types are exported. | ||
#### Apollo | ||
Written in TypeScript; types are exported. | ||
### Next.js integration | ||
#### graphql-react | ||
Has [an official example](https://github.com/zeit/next.js/tree/canary/examples/with-graphql-react) using [`next-graphql-react`](https://npm.im/next-graphql-react), which provides easy an easy to install [`App`](https://nextjs.org/docs/#custom-app) decorator and [plugin](https://nextjs.org/docs/#custom-configuration) to enable server side rendered GraphQL queries. | ||
#### Apollo | ||
Has [an official example](https://github.com/zeit/next.js/tree/canary/examples/with-apollo), but it consists of over 100 lines of complicated copy-paste boilerplate code across multiple files. |
@@ -22,12 +22,7 @@ 'use strict' | ||
var fetchOptionsOverride = _ref.fetchOptionsOverride, | ||
_ref$loadOnMount = _ref.loadOnMount, | ||
loadOnMount = _ref$loadOnMount === void 0 ? true : _ref$loadOnMount, | ||
_ref$loadOnReload = _ref.loadOnReload, | ||
loadOnReload = _ref$loadOnReload === void 0 ? true : _ref$loadOnReload, | ||
_ref$loadOnReset = _ref.loadOnReset, | ||
loadOnReset = _ref$loadOnReset === void 0 ? true : _ref$loadOnReset, | ||
_ref$reloadOnLoad = _ref.reloadOnLoad, | ||
reloadOnLoad = _ref$reloadOnLoad === void 0 ? false : _ref$reloadOnLoad, | ||
_ref$resetOnLoad = _ref.resetOnLoad, | ||
resetOnLoad = _ref$resetOnLoad === void 0 ? false : _ref$resetOnLoad, | ||
loadOnMount = _ref.loadOnMount, | ||
loadOnReload = _ref.loadOnReload, | ||
loadOnReset = _ref.loadOnReset, | ||
reloadOnLoad = _ref.reloadOnLoad, | ||
resetOnLoad = _ref.resetOnLoad, | ||
operation = _ref.operation | ||
@@ -113,3 +108,8 @@ if (reloadOnLoad && resetOnLoad) | ||
var exceptCacheKey = _ref4.exceptCacheKey | ||
if (cacheKey !== exceptCacheKey && loadOnReload && isMountedRef.current) | ||
if ( | ||
cacheKey !== exceptCacheKey && | ||
loadOnReload && | ||
cacheValue && | ||
isMountedRef.current | ||
) | ||
load() | ||
@@ -137,3 +137,3 @@ } | ||
}, | ||
[cacheKey, graphql, load, loadOnReload, loadOnReset] | ||
[cacheKey, cacheValue, graphql, load, loadOnReload, loadOnReset] | ||
) | ||
@@ -140,0 +140,0 @@ |
Sorry, the diff of this file is not supported yet
88884
789
Updated@babel/runtime@^7.5.5