Package Exports
- @hasura-ws/hooks
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@hasura-ws/hooks) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@hasura-ws/hooks
Hooks are used together with prepare
to offer a react API to consume
queries
All hooks takes 3 arguments:
- the prepared query
- the variables
- the inputs passed to
useEffect
to tell react when to refresh
useQuery
import { initClient } from '@hasura-ws/browser'
import { initPrepare } from '@hasura-ws/prepare'
import { useQuery, isPending, hasError, isReloading } from '@hasura-ws/hooks'
const client = initClient({
address: 'ws://localhost:8080/v1alpha1/graphql',
token: 'eyJhbGciOiJIUzI...w5c',
})
const prepare = initPrepare(client)
const getUserEmail = prepare(`query getUserById($id: Int!) {
user (where: {id: {_eq: $id}}) {
email
}
}`)
const MyQueryComponent = ({ id }) => {
const users = useQuery(getUserEmail, { id }, [id])
if (isPending(users)) return 'Loading...'
if (hasError(users)) return 'Oops !'
if (!users.length) return 'Not found'
const { email } = users[0]
return <div class={isReloading(users) ? 'loading' : ''}>{email}</div>
}
// Or using `.one` to get one user directly:
const MyQueryComponent = ({ id }) => {
const user = useQuery(getUserEmail.one, { id }) // we can also omit inputs
// Omitted inputs are generated using Object.values(variables),
// so it is equivalent to [ id ] in that case.
if (isPending(user)) return 'Loading...'
if (hasError(user)) return 'Oops !'
if (!user) return 'Not found'
return <div>{user.email}</div>
}
useSubscribe
const userSubscribe = prepare(`
subscription subscribeToUserById($id: Int!) {
user (where: {id: {_eq: $id}}) {
email
}
}`)
const MySubscribeComponent = ({ id }) => {
const user = useSubscribe(userSubscribe.one, { id }, [id])
if (isPending(user)) return 'Loading...'
if (hasError(user)) return 'Oops !'
if (!user) return 'Not found'
return <div>{user.email}</div>
}
useMutation
// You should try have the useMutation in it's separate component
// so that the pending update doesn't trigger a rerender of the rest
// of your app.
const MyUpdateButton = ({ id, email, showMessage }) => {
const updateUser = useMutation(updateUserMutation)
return (
<button
disabled={updateUser.pending}
onClick={
() =>
updateUser.run({ id, changes: { email } })
.then(() => showMessage('update successfull'))
.catch(err => showMessage(`update failed: ${err.message}`))
// With mutations, you need to handle errors manualy
// they arent catched and passed for you.
}
/>
)
}
const MyMutationComponent = ({ id }) => {
const [email, setEmail] = useState()
const [message, setMessage] = useState('')
return (
<div>
<input value={email} onChange={e => setEmail(e.target.value)} />
<MyUpdateButton email={email} id={id} setMessage={message} />
<pre>{message}</pre>
</div>
)
}
prepareWithHooks
A prefered version of prepare
that also add hooks to your query.
import { initClient } from '@hasura-ws/browser'
import { initPrepareWithHooks, hasError, isPending } from '@hasura-ws/hooks'
const client = initClient({
address: 'ws://localhost:8080/v1alpha1/graphql',
token: 'eyJhbGciOiJIUzI...w5c',
})
const prepare = initPrepareWithHooks(client)
const userSubscribe = prepare(`
subscription subscribeToUserById($id: Int!) {
user (where: {id: {_eq: $id}}) {
email
}
}`)
// prepare hooks gives a hook for each prepare methods:
// use, useOne, useAll and useMap.
// Here an example of useOne:
const MySubscribeComponent = ({ id }) => {
const user = userSubscribe.useOne({ id })
if (isPending(user)) return 'Loading...'
if (hasError(user)) return 'Oops !'
if (!user) return 'User not found !'
return <div>{user.email}</div>
}
buildModelWithHooks
import { initClient } from '@hasura-ws/browser'
import { buildModelWithHooks, initPrepareWithHooks } from '@hasura-ws/hooks'
const client = initClient({
address: 'ws://localhost:8080/v1alpha1/graphql',
token: 'eyJhbGciOiJIUzI...w5c',
})
const prepare = initPrepareWithHooks(client)
const model = buildModelWithHooks(prepare)
Using hooks, the model also expose a react hooks for each actions:
.useGet(id)
.useAdd({ a: 1, b: 2 }, [1, 2])
.useRemove(id)
.useUpdate({ id, a: 1, b: 2 }, [1, 2])
.useSubscribe(id)
It's just the correct hook and the model method.
As such useAdd
is useMutation
for user.add
.
model.useUpdate
const MyComponent = ({ userId }) => {
const updateUser = userModel.useUpdate()
return (
<button
disabled={updateUser.pending}
onClick={() => updateUser.run({ id: userId, email: 'jean@mail.com' })}
/>
)
}
initAll
This can be use to combine prepareWithHooks
and buildModelWithHooks
import { initClient } from '@hasura-ws/browser'
import { initAll } from '@hasura-ws/hooks'
const { client, model, prepare } = initAll(initClient({
address: 'ws://localhost:8080/v1alpha1/graphql',
token: 'eyJhbGciOiJIUzI...w5c',
}))