One simple Typescript/React hook used to fetch data from a GraphQL endpoint.
use-graphql-ts aims to cover the generic GraphQL usage inside a React/Typescript environment providing a helpful API to bring you the query/mutation result in a simple and clean way with types included (if you want).
It supports @dotansimha/graphql-typed-document-node as an input source as well as a normal GraphQL DocumentNode
.
In the future, more features may be implemented.
npm i --save use-graphql-ts
In this example we use a TypedDocumentNode generated from our query.
query.graphql
query getUser {
user {
username
}
}
username.tsx
import { useGraphQL } from "use-graphql-ts"
import { GetUserDocument } from "./generated-types"
function Username({ email }) {
const { data, errors, loaded } = useGraphQL({
operation: GetUserDocument, // <- TypedDocumentNode
variables: { email } // <- type checking here!
})
const displayUsername = () => {
if (loaded) {
if (errors) {
return `An error occurred: ${errors[0].message}`
)
}
return `Username: ${data.user.username}` // <- type checking here!
}
return "Loading..."
}
return (
<span>
{displayUsername()}
</span>
)
}
Here we pass a document node directly so to get type checking we'll need to manually pass our data types
query.graphql
query getUser {
user {
username
}
}
types.ts
interface User {
...
username: string
...
}
export type Data = Record<"user", User>
export type Variables = Record<"email", string>
username.tsx
import { useGraphQL } from "use-graphql-ts"
import Query from "./query.graphql"
import { Data, Variables } from "./types"
function Username({ email }) {
const { data, ok } = useGraphQL<Data, Variables>({
operation: Query,
variables: { email } // <- will be checked against Variables generic argument
})
return (
<span>
Username: {ok && data.user.username /* <- Type checking here */}
</span>
)
}
In this example we can see how to execute the operation only when we call it.
import { useGraphQL } from "use-graphql-ts"
function DeleteUser({ email }) {
const { ok, execute } = useGraphQL({
operation: `mutation($email: String!) {
deleteUser(email: $email)
}`, // <- we can pass a string for the operation.
variables: { email },
passive: true // <- this stops the operation from being executed until we call it with execute()
})
const executeDelete = async () => {
await execute()
if (ok) {
alert("User deleted successfully.")
} else {
alert("Something went wrong!")
}
}
return (
<button onClick={() => executeDelete()}>
Delete this user
</button>
)
}
useGraphQL returns an Object
with the following properties:
data: Record<string, any>
errors: Error[]
loaded: boolean
ok: boolean
execute: () => Promise<void>
reset: () => void
- data: the response you get from a successful GraphQL request.
null
if errors occurred or the request didn't load yet. - errors: the errors array you get from GraphQL when one or more errors occurred.
null
if the server responded withdata
- loaded:
true
when the server responds and the promise is fullfilled. Otherwisefalse
. Note that this will betrue
even when errors occured. - ok:
true
when the server responds withdata
anderrors
isnull
. Useful to check if data is retrieved without errors. - execute: an
async function
which executes the request. Useful if you need to refresh the result or usingpassive: true
. - reset: a
function
that sets alla the return values to initial.
The useGraphQL function accepts an object as its only argument with the following properties:
operation: DocumentNode | TypedDocumentNode | string
variables?: Record<string, any> // defaults to null
token?: string //defaults to null
passive?: boolean // defaults to false
endpoint?: string // defaults to "/graphql"
- operation - Non-Optional: This is the mutation or query request you send to the GraphQL endpoint. Can be a
TypedDocumentNode
, aDocumentNode
or aString
. - variables - Optional: The variables object used by the GraphQL operation.
- token - Optional: An authorization token which will be sent with the Authorization header as
Bearer <token>
. - passive - Optional: Determines if the GraphQL request will be executed immediatly or not. If passed
true
the request will only run when you callexecute()
, otherwise if passedfalse
it will run as soon as the component renders. Defaults tofalse
- endpoint: the GraphQL endpoint. Defaults to
/graphql
The function accepts two generic arguments for defining returned data and variables types:
function useGraphQL<DataType, VariablesType>