Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jaydenseric/graphql-react
A GraphQL client for React using modern context and hooks APIs that is lightweight (< 4 kB) but powerful; the first Relay and Apollo alternative with server side rendering.
https://github.com/jaydenseric/graphql-react
deno esm graphql hooks maintained mjs node npm react typescript
Last synced: 3 days ago
JSON representation
A GraphQL client for React using modern context and hooks APIs that is lightweight (< 4 kB) but powerful; the first Relay and Apollo alternative with server side rendering.
- Host: GitHub
- URL: https://github.com/jaydenseric/graphql-react
- Owner: jaydenseric
- License: mit
- Created: 2018-02-02T05:56:35.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2024-07-12T07:44:26.000Z (6 months ago)
- Last Synced: 2024-10-29T17:28:21.702Z (2 months ago)
- Topics: deno, esm, graphql, hooks, maintained, mjs, node, npm, react, typescript
- Language: JavaScript
- Homepage: https://npm.im/graphql-react
- Size: 1.25 MB
- Stars: 718
- Watchers: 13
- Forks: 22
- Open Issues: 2
-
Metadata Files:
- Readme: readme.md
- Changelog: changelog.md
- Funding: .github/funding.yml
- License: license.md
Awesome Lists containing this project
- awesome - jaydenseric/graphql-react - A GraphQL client for React using modern context and hooks APIs that is lightweight (< 4 kB) but powerful; the first Relay and Apollo alternative with server side rendering. (JavaScript)
- stars - jaydenseric/graphql-react
- awesome-list - graphql-react
README
![graphql-react logo](https://cdn.jsdelivr.net/gh/jaydenseric/[email protected]/graphql-react-logo.svg)
# graphql-react
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’s lightweight (< 4 kB) but powerful; the first [Relay](https://relay.dev) and [Apollo](https://apollographql.com/apollo-client) alternative with server side rendering.
The [exports](#exports) can also be used to custom load, cache and server side render any data, even from non-[GraphQL](https://graphql.org) sources.
- [Installation](#installation)
- [Examples](#examples)
- [Requirements](#requirements)
- [Exports](#exports)## Installation
> **Note**
>
> For a [Next.js](https://nextjs.org) project, see the [`next-graphql-react`](https://npm.im/next-graphql-react) installation instructions.For [Node.js](https://nodejs.org), to install [`graphql-react`](https://npm.im/graphql-react) and its [`react`](https://npm.im/react) peer dependency with [npm](https://npmjs.com/get-npm), run:
```sh
npm install graphql-react react
```For [Deno](https://deno.land) and browsers, an example import map (realistically use 4 import maps, with optimal URLs for server vs client and development vs production):
```json
{
"imports": {
"extract-files/": "https://unpkg.com/[email protected]/",
"graphql-react/": "https://unpkg.com/[email protected]/",
"is-plain-obj": "https://unpkg.com/[email protected]/index.js",
"is-plain-obj/": "https://unpkg.com/[email protected]/",
"react": "https://esm.sh/[email protected]",
"react-waterfall-render/": "https://unpkg.com/[email protected]/"
}
}
```These dependencies might not need to be in the import map, depending on what [`graphql-react`](https://npm.im/graphql-react) modules the project imports from:
- [`extract-files`](https://npm.im/extract-files)
- [`is-plain-obj`](https://npm.im/is-plain-obj)
- [`react-waterfall-render`](https://npm.im/react-waterfall-render)Polyfill any required globals (see [_**Requirements**_](#requirements)) that are missing in your server and client environments.
Create a single [`Cache`](./Cache.mjs) instance and use the component [`Provider`](./Provider.mjs) to provide it for your app.
To server side render your app, use the function [`waterfallRender`](https://github.com/jaydenseric/react-waterfall-render#exports) from [`react-waterfall-render`](https://npm.im/react-waterfall-render).
## Examples
- [`graphql-react` examples repo](https://github.com/jaydenseric/graphql-react-examples), a [Deno](https://deno.land) [Ruck](https://ruck.tech) web app deployed at [graphql-react-examples.fly.dev](https://graphql-react-examples.fly.dev).
- [Official Next.js example](https://github.com/vercel/next.js/tree/canary/examples/with-graphql-react) (often outdated as the Next.js team can be extremely slow to review and merge pull requests).Here is a basic example using the [GitHub GraphQL API](https://docs.github.com/en/graphql), with tips commented:
```jsx
import useAutoLoad from "graphql-react/useAutoLoad.mjs";
import useCacheEntry from "graphql-react/useCacheEntry.mjs";
import useLoadGraphQL from "graphql-react/useLoadGraphQL.mjs";
import useWaterfallLoad from "graphql-react/useWaterfallLoad.mjs";
import React from "react";// The query is just a string; no need to use `gql` from `graphql-tag`. The
// special comment before the string allows editor syntax highlighting, Prettier
// formatting and linting. The cache system doesn’t require `__typename` or `id`
// fields to be queried.
const query = /* GraphQL */ `
query ($repoId: ID!) {
repo: node(id: $repoId) {
... on Repository {
stargazers {
totalCount
}
}
}
}
`;export default function GitHubRepoStars({ repoId }) {
const cacheKey = `GitHubRepoStars-${repoId}`;
const cacheValue = useCacheEntry(cacheKey);// A hook for loading GraphQL is available, but custom hooks for loading non
// GraphQL (e.g. fetching from a REST API) can be made.
const loadGraphQL = useLoadGraphQL();const load = React.useCallback(
() =>
// To be DRY, utilize a custom hook for each API your app loads from, e.g.
// `useLoadGraphQLGitHub`.
loadGraphQL(
cacheKey,
// Fetch URI.
"https://api.github.com/graphql",
// Fetch options.
{
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
Authorization: `Bearer ${process.env.GITHUB_ACCESS_TOKEN}`,
},
body: JSON.stringify({
query,
variables: {
repoId,
},
}),
},
),
[cacheKey, loadGraphQL, repoId],
);// This hook automatically keeps the cache entry loaded from when the
// component mounts, reloading it if it’s staled or deleted. It also aborts
// loading if the arguments change or the component unmounts; very handy for
// auto-suggest components!
useAutoLoad(cacheKey, load);// Waterfall loading can be used to load data when server side rendering,
// enabled automagically by `next-graphql-react`. To learn how this works or
// to set it up for a non-Next.js app, see:
// https://github.com/jaydenseric/react-waterfall-render
const isWaterfallLoading = useWaterfallLoad(cacheKey, load);// When waterfall loading it’s efficient to skip rendering, as the app will
// re-render once this step of the waterfall has loaded. If more waterfall
// loading happens in children, those steps of the waterfall are awaited and
// the app re-renders again, and so forth until there’s no more loading for
// the final server side render.
return isWaterfallLoading
? null
: cacheValue
? cacheValue.errors
? // Unlike many other GraphQL libraries, detailed loading errors are
// cached and can be server side rendered without causing a
// server/client HTML mismatch error.
"Error!"
: cacheValue.data.repo.stargazers.totalCount
: // In this situation no cache value implies loading. Use the
// `useLoadingEntry` hook to manage loading in detail.
"Loading…";
}
```## Requirements
Supported runtime environments:
- [Node.js](https://nodejs.org) versions `^18.18.0 || ^20.9.0 || >=22.0.0`.
- [Deno](https://deno.land), importing from a CDN that might require an import map for dependencies.
- Browsers matching the [Browserslist](https://browsersl.ist) query [`> 0.5%, not OperaMini all, not dead`](https://browsersl.ist/?q=%3E+0.5%25%2C+not+OperaMini+all%2C+not+dead).Consider polyfilling:
- [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController)
- [`CustomEvent`](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent)
- [`Event`](https://developer.mozilla.org/en-US/docs/Web/API/Event)
- [`EventTarget`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget)
- [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
- [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData)
- [`performance`](https://developer.mozilla.org/en-US/docs/Web/API/Window/performance)Non [Deno](https://deno.land) projects must configure [TypeScript](https://typescriptlang.org) to use types from the ECMAScript modules that have a `// @ts-check` comment:
- [`compilerOptions.allowJs`](https://typescriptlang.org/tsconfig#allowJs) should be `true`.
- [`compilerOptions.maxNodeModuleJsDepth`](https://typescriptlang.org/tsconfig#maxNodeModuleJsDepth) should be reasonably large, e.g. `10`.
- [`compilerOptions.module`](https://typescriptlang.org/tsconfig#module) should be `"node16"` or `"nodenext"`.## Exports
The [npm](https://npmjs.com) package [`graphql-react`](https://npm.im/graphql-react) features [optimal JavaScript module design](https://jaydenseric.com/blog/optimal-javascript-module-design). It doesn’t have a main index module, so use deep imports from the ECMAScript modules that are exported via the [`package.json`](./package.json) field [`exports`](https://nodejs.org/api/packages.html#exports):
- [`Cache.mjs`](./Cache.mjs)
- [`CacheContext.mjs`](./CacheContext.mjs)
- [`cacheDelete.mjs`](./cacheDelete.mjs)
- [`cacheEntryDelete.mjs`](./cacheEntryDelete.mjs)
- [`cacheEntryPrune.mjs`](./cacheEntryPrune.mjs)
- [`cacheEntrySet.mjs`](./cacheEntrySet.mjs)
- [`cacheEntryStale.mjs`](./cacheEntryStale.mjs)
- [`cachePrune.mjs`](./cachePrune.mjs)
- [`cacheStale.mjs`](./cacheStale.mjs)
- [`fetchGraphQL.mjs`](./fetchGraphQL.mjs)
- [`fetchOptionsGraphQL.mjs`](./fetchOptionsGraphQL.mjs)
- [`HYDRATION_TIME_MS.mjs`](./HYDRATION_TIME_MS.mjs)
- [`HydrationTimeStampContext.mjs`](./HydrationTimeStampContext.mjs)
- [`Loading.mjs`](./Loading.mjs)
- [`LoadingCacheValue.mjs`](./LoadingCacheValue.mjs)
- [`LoadingContext.mjs`](./LoadingContext.mjs)
- [`Provider.mjs`](./Provider.mjs)
- [`types.mjs`](./types.mjs)
- [`useAutoAbortLoad.mjs`](./useAutoAbortLoad.mjs)
- [`useAutoLoad.mjs`](./useAutoLoad.mjs)
- [`useCache.mjs`](./useCache.mjs)
- [`useCacheEntry.mjs`](./useCacheEntry.mjs)
- [`useCacheEntryPrunePrevention.mjs`](./useCacheEntryPrunePrevention.mjs)
- [`useLoadGraphQL.mjs`](./useLoadGraphQL.mjs)
- [`useLoading.mjs`](./useLoading.mjs)
- [`useLoadingEntry.mjs`](./useLoadingEntry.mjs)
- [`useLoadOnDelete.mjs`](./useLoadOnDelete.mjs)
- [`useLoadOnMount.mjs`](./useLoadOnMount.mjs)
- [`useLoadOnStale.mjs`](./useLoadOnStale.mjs)
- [`useWaterfallLoad.mjs`](./useWaterfallLoad.mjs")