MCPcopy
hub / github.com/nearform/graphql-hooks

github.com/nearform/graphql-hooks @8.2.0 sqlite

repository ↗ · DeepWiki ↗ · release 8.2.0 ↗
238 symbols 658 edges 126 files 4 documented · 2%
README

graphql-hooks

ci Coverage Status bundlephobia npm lerna

🎣 Minimal hooks-first GraphQL client.

Features

  • 🥇 First-class hooks API
  • ⚖️ Tiny bundle: only 22.9kB (7.4kB gzipped)
  • 📄 Full SSR support: see graphql-hooks-ssr
  • 🔌 Plugin Caching: see graphql-hooks-memcache
  • 🔥 No more render props hell
  • ⏳ Handle loading and error states with ease

Install

npm install graphql-hooks

or

yarn add graphql-hooks

Support

Consider polyfilling:

Quick Start

First you'll need to create a client and wrap your app with the provider:

import { GraphQLClient, ClientContext } from 'graphql-hooks'

const client = new GraphQLClient({
  url: '/graphql'
})

function App() {
  return (
    <ClientContext.Provider value={client}>
      {/* children */}
    </ClientContext.Provider>
  )
}

Now in your child components you can make use of useQuery

import { useQuery } from 'graphql-hooks'

const HOMEPAGE_QUERY = `query HomePage($limit: Int) {
  users(limit: $limit) {
    id
    name
  }
}`

function MyComponent() {
  const { loading, error, data } = useQuery(HOMEPAGE_QUERY, {
    variables: {
      limit: 10
    }
  })

  if (loading) return 'Loading...'
  if (error) return 'Something Bad Happened'

  return (
    <ul>
      {data.users.map(({ id, name }) => (
        <li key={id}>{name}</li>
      ))}
    </ul>
  )
}

Why graphql-hooks?

The first thing you may ask when seeing graphql-hooks is "Why not use Apollo hooks?". It's the comparison most will make. In fact, there's an article comparing the two over on LogRocket.

We believe graphql-hooks is a great choice as a hooks-first GraphQL client due to its concise API and package size.

In terms of performance, this is more of a grey area as we have no official benchmarks yet.

If you need a client that offers more customization such as advanced cache configuration, then apollo-hooks may work out to be a good choice for your project if bundle size is not an issue.

Pros Cons
Small in size Less "advanced" caching configuration
Concise API
Quick to get up and running

Table of Contents

API

GraphQLClient

Usage:

import { GraphQLClient } from 'graphql-hooks'
const client = new GraphQLClient(config)

config: Object containing configuration properties

  • url: The URL of your GraphQL HTTP server. If not specified, you must enable fullWsTransport and provide a valid subscriptionClient; otherwise is required.
  • fullWsTransport: Boolean - set to true if you want to use subscriptionClient to also send query and mutations via WebSocket; defaults to false
  • ssrMode: Boolean - set to true when using on the server for server-side rendering; defaults to false
  • useGETForQueries: Boolean - set to true to use HTTP GET method for all queries; defaults to false. See HTTP Get Support for more info
  • subscriptionClient: The WebSocket client configuration. Accepts either an instance of SubscriptionClient from subscriptions-transport-ws or Client from graphql-ws. A factory function is also accepted e.g. to avoid the creation of the client in SSR environments.
  • cache (Required if ssrMode is true, otherwise optional): Object with the following methods:
  • cache.get(key)
  • cache.set(key, data)
  • cache.delete(key)
  • cache.clear()
  • cache.keys()
  • getInitialState()
  • See graphql-hooks-memcache as a reference implementation
  • fetch(url, options): Fetch implementation - defaults to the global fetch API. Check Request interceptors for more details how to manage fetch.
  • FormData: FormData implementation - defaults to the global FormData API. Polyfill this in a node.js environment. See file-uploads-nodejs for more info.
  • fetchOptions: See MDN for info on what options can be passed
  • headers: Object, e.g. { 'My-Header': 'hello' }
  • logErrors: Boolean - defaults to true
  • middleware: Accepts an array of middleware functions, default: none, see more in middlewares readme
  • onError({ operation, result }): Custom error handler
  • operation: Object with query, variables and operationName
  • result: Object containing data, headers and error object that contains fetchError, httpError and graphqlErrors

client methods

  • client.setHeader(key, value): Updates client.headers adding the new header to the existing headers
  • client.setHeaders(headers): Replaces client.headers
  • client.removeHeader(key): Updates client.headers removing the header if it exists
  • client.logErrorResult({ operation, result }): Default error logger; useful if you'd like to use it inside your custom onError handler
  • request(operation, options): Make a request to your GraphQL server; returning a Promise
  • operation: Object with query, variables and operationName
  • options.fetchOptionsOverrides: Object containing additional fetch options to be added to the default ones passed to new GraphQLClient(config)
  • options.responseReducer: Reducer function to pick values from the original Fetch Response object. Values are merged to the request response under the data key. Example usage: {responseReducer: (data, response) => ({...data, myKey: response.headers.get('content-length)})
  • client.invalidateQuery(query): Will delete the older cache, re-fetch the new data using the same query, and store it in the cache as a new value
  • query: The GraphQL query as a plain string to be re-fetched, or an Operation object (with query, variables and operationName)
  • client.setQueryData(query, (oldState) => [...oldState, newState]]): Will override the older cache state with the new one provided by the function return
  • query: The GraphQL query as a plain string, or an Operation object (with query, variables and operationName)
  • (oldState) => [...oldState, newState]]: The callback function with returns will be the new state stored in the cache.
    • oldState: The old value stored in the cache

ClientContext

ClientContext is the result of React.createContext() - meaning it can be used directly with React's new context API:

Example:

import { ClientContext } from 'graphql-hooks'

function App() {
  return (
    <ClientContext.Provider value={client}>
      {/* children can now consume the client context */}
    </ClientContext.Provider>
  )
}

To access the GraphQLClient instance, call React.useContext(ClientContext):

import React, { useContext } from 'react'
import { ClientContext } from 'graphql-hooks'

function MyComponent() {
  const client = useContext(ClientContext)
}

useQuery

Usage:

const state = useQuery(query, [options])

Example:

import { useQuery } from 'graphql-hooks'

function MyComponent() {
  const { loading, error, data } = useQuery(query)

  if (loading) return 'Loading...'
  if (error) return 'Something bad happened'

  return 

{data.thing}


}

This is a custom hook that takes care of fetching your query and storing the result in the cache. It won't refetch the query unless query or options.variables changes.

  • query: Your GraphQL query as a plain string or DocumentNode
  • options: Object with the following optional properties
  • variables: Object e.g. { limit: 10 }
  • operationName: If your query has multiple operations, pass the name of the operation you wish to execute.
  • persisted: Boolean - defaults to false; Pass true if your graphql server supports persisted flag to serve persisted queries.
  • useCache: Boolean - defaults to true; cache the query result
  • skip: Boolean - defaults to false; do not execute the query if set to true
  • skipCache: Boolean - defaults to false; If true it will by-pass the cache and fetch, but the result will then be cached for subsequent calls. Note the refetch function will do this automatically
  • ssr: Boolean - defaults to true. Set to false if you wish to skip this query during SSR
  • fetchOptionsOverrides: Object - Specific overrides for this query. See MDN for info on what options can be passed
  • updateData(previousData, data): Function - Custom handler for merging previous & new query results; return value will replace data in useQuery return value
    • previousData: Previous GraphQL query or updateData result
    • data: New GraphQL query result
  • client: GraphQLClient - If a GraphQLClient is explicitly passed as an option, then it will be used instead of the client from the ClientContext.
  • refetchAfterMutations: String | Object | (String | Object)[] - You can specify when a mutation should trigger query refetch.
    • If it's a string, it's the mutation string
    • If it's an object then it has properties mutation and filter
    • mutation: String - The mutation string
    • refetchOnMutationError: boolean (optional, defaults to true) - It indicates whether the query must be re-fetched if the mutation returns an error
    • filter: Function (optional) - It receives mutation's variables as parameter and blocks refetch if it returns false
    • If it's an array, the elements can be of either type above

useQuery return value

const { loading, error, data, refetch, cacheHit } = useQuery(QUERY)
  • loading: Boolean - true if the query is in flight
  • data: Object - the result of your GraphQL query
  • headers: Object - response headers
  • refetch(options): Function - useful when refetching the same query after a mutation; NOTE this presets skipCache=true & will bypass the options.updateData function that was passed into useQuery. You can pass a new updateData into refetch if necessary.
  • options: Object - options that will be merged into the options that were passed into useQuery (see above).
  • cacheHit: Boolean - true if the query result came from the cache, useful for debugging
  • error: Object - Set if at least one of the following errors has occurred and contains:
  • fetchError: Object - Set if an error occurred during the fetch call
  • httpError: Object - Set if an error response was returned from the server
  • graphQLErrors: Array - Populated if any errors occurred whilst resolving the query

useManualQuery

Use this when you don't want a query to automatically be fetched or wish to call a query programmatically.

Usage:

const [queryFn, state] = useManualQuery(query, [options])

Example:

import { useManualQuery } from 'graphql-hooks'

function MyComponent(props) {
  const [fetchUser, { loading, error, data }] = useManualQuery(GET_USER_QUERY, {
    variables: { id: props.userId }
  })

  return (



      <button onClick={fetchUser}>Get User!</button>
      {error && 

Failed to fetch user

}
      {loading && 

Loading...

}
      {data && 

Hello ${data.user.name}

}



  )
}

If you don't know certain options when declaring the useManualQuery you can also pass the same options to the query function itself when calling it:

```js import { useManualQuery }

Extension points exported contracts — how you extend this code

Options (Interface)
(no doc) [2 implementers]
packages/graphql-hooks-ssr/index.d.ts
MemCache (Interface)
(no doc)
packages/graphql-hooks-memcache/index.d.ts
GraphQLResponseErrorLocation (Interface)
(no doc)
packages/graphql-hooks/src/types/common-types.ts
PostData (Interface)
(no doc)
examples/typescript/src/App.tsx
Client (Interface)
(no doc)
packages/graphql-hooks-ssr/index.d.ts
GraphQLResponseError (Interface)
(no doc)
packages/graphql-hooks/src/types/common-types.ts
Cache (Interface)
(no doc)
packages/graphql-hooks-ssr/index.d.ts
ClientOptions (Interface)
(no doc)
packages/graphql-hooks/src/types/common-types.ts

Core symbols most depended-on inside this repo

useQuery
called by 65
packages/graphql-hooks/src/useQuery.ts
useClientRequest
called by 44
packages/graphql-hooks/src/useClientRequest.ts
fnv1a
called by 16
packages/graphql-hooks-memcache/src/fnv1a.js
useSubscription
called by 13
packages/graphql-hooks/src/useSubscription.ts
get
called by 13
packages/graphql-hooks/src/types/common-types.ts
set
called by 12
packages/graphql-hooks-memcache/index.d.ts
memCache
called by 12
packages/graphql-hooks-memcache/src/index.js
get
called by 11
packages/graphql-hooks-memcache/index.d.ts

Shape

Function 138
Method 56
Interface 25
Class 18
Enum 1

Languages

TypeScript100%

Modules by API surface

packages/graphql-hooks/src/types/common-types.ts32 symbols
packages/graphql-hooks/src/GraphQLClient.ts24 symbols
packages/graphql-hooks/test-jsdom/unit/useSubscription.test.tsx13 symbols
packages/graphql-hooks/src/LocalGraphQLClient.ts11 symbols
packages/graphql-hooks/test-jsdom/unit/useClientRequest.test.tsx7 symbols
packages/graphql-hooks/test-jsdom/integration/useQuery.test.tsx7 symbols
packages/graphql-hooks-memcache/index.d.ts7 symbols
examples/typescript/src/App.tsx7 symbols
packages/graphql-hooks/src/useClientRequest.ts6 symbols
packages/babel-plugin-extract-gql/src/index.js6 symbols
examples/create-react-app/src/components/ErrorBoundary.js6 symbols
packages/graphql-hooks-ssr/index.d.ts5 symbols

Used by 1 indexed graphs manifest dependencies, hub-wide

Dependencies from manifests, versioned

@0no-co/graphql.web1.0.7 · 1×
@aws-crypto/sha256-browser5.2.0 · 1×
@babel/cli7.0.0 · 1×
@babel/core7.16.12 · 1×
@babel/eslint-parser7.16.5 · 1×
@babel/plugin-proposal-object-rest-spread7.20.7 · 1×
@babel/plugin-transform-object-rest-spread7.22.5 · 1×
@babel/preset-env7.14.1 · 1×
@babel/preset-react7.13.13 · 1×
@babel/preset-typescript7.18.6 · 1×
@babel/register7.0.0 · 1×
@commitlint/cli19.3.0 · 1×

For agents

$ claude mcp add graphql-hooks \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact