apollo-react-client
TypeScript icon, indicating that this package has built-in type declarations

0.0.11 • Public • Published

Apollo React Client

This library contains a set of utility functions to work with apollo-client for React

How to install

Using yarn

yarn add apollo-react-client graphql

Using npm

npm install apollo-react-client graphql

Usage

Configure Provider

For React Native

import { ApolloClientProvider } from 'apollo-react-client'
import AsyncStorage from '@react-native-community/async-storage';

export function App() {
  return (
    <ApolloClientProvider serviceURL='http://localhost:3000' storage={AsyncStorage}>
      <HomeScreen />
    </ApolloClientProvider>
  )
}

For React

import { ApolloClientProvider } from 'apollo-react-client'

export function App() {
  return (
    <ApolloClientProvider serviceURL='http://localhost:3000' storage={window.localStorage}>
      <HomeScreen />
    </ApolloClientProvider>
  )
}

To get client

// from with in ApolloClientProvider
const { client, cache } = useApolloClient()

Use Query

Fetch Single entity

import { gql } from '@apollo/client'
import { useQuery } from 'apollo-react-client'

const FETCH_USER_QUERY = gql`
  query fetchUser($id: ID!) {
    user(id: $id) {
      id
      name
      email
      photoURL
    }
  }
`

interface Request {
  id: string
}

interface Response {
  id?: string
  name?: string
  email?: string
  photoURL?: string
}

export function useUser(request: Request) {
  return useQuery<Response | null, Request>(FETCH_USER_QUERY, request, {
    skip: request?.id == null,
  })
}

export function App() {
  const id = 'user_id'
  const [user, { loading, error }] = useUser({ id })
  console.log(user?.id, user?.name, loading, error)
}

Fetch multiple entities

(Pagination coming soon)

import { gql } from '@apollo/client'
import { useQuery } from 'apollo-react-client'

export const FETCH_ALL_USERS_QUERY = gql`
  query fetchAllUsers() {
    allUsers() {
      id
      name
      email
      photoURL
    }
  }
`

interface Response {
  id?: string
  name?: string
  email?: string
  photoURL?: string
}

export function useAllUsers() {
  return useQuery<Response[] | null, never>(FETCH_ALL_USERS_QUERY)
}

export function App() {
  const [users, { loading, error }] = useAllUsers()
  console.log(users, loading, error)
}

Use Mutation

Creating a user

import { gql } from '@apollo/client'
import React, { useCallback } from 'react'
import { patchQuery, useMutation } from 'apollo-react-client'
import { FETCH_ALL_USERS_QUERY } from './use-users'

interface CreateUserRequest {
  name: string
  email: string
  password: string | null
}

interface Response {
  id?: string
  name?: string
  email?: string
  photoURL?: string
}

const CREATE_USER_MUTATION = gql`
  mutation createUserMutation($user: CreateUserRequest!) {
    createUser(user: $user) {
      id
      name
      email
      photoURL
    }
  }
`

export function useCreateUser() {
  return useMutation<Response, { user: CreateUserRequest }, { user: CreateUserRequest }>(
    CREATE_USER_MUTATION,
    {
      beforeMutation: async (variables?: { user: CreateUserRequest }) => {
        const { user } = variables || {}
        if (!user) {
          throw new Error('Invalid user')
        }
        // do your stuff or remap variables
        return { user }
      },
      afterMutation: async (data?: Response | null, variables?: { user: CreateUserRequest }) => {
        console.log(data, variables)
        // do your stuff or remap data
        return data
      },
      update: patchQuery<Response[], never, { createUser: Response }>(
        { query: FETCH_ALL_USERS_QUERY },
        // add user to the end of list
        (users, result) => [...(users || []), result?.createUser as Response],
      ),
    },
  )
}

export function App() {
  const [createUser, { loading, error }] = useCreateUser()

  const onCreate = useCallback(async () => {
    const user = { name: 'JohnDoe', email: 'johnd@gmail.com', password: 'Password@123' }
    await createUser({ user })
  }, [createUser])

  if (error) {
    return <div className='error'>{error}</div>
  }

  return (
    <button disabled={loading} onClick={onCreate}>
      Create
    </button>
  )
}

Removing a user

import { gql } from '@apollo/client'
import { useCallback } from 'react'
import { patchQuery, useMutation } from 'apollo-react-client'
import { FETCH_ALL_USERS_QUERY } from './use-users'

const REMOVE_USER_MUTATION = gql`
  mutation removeUser($id: ID!) {
    removeUser(id: $id) {
      id
    }
  }
`

interface Request {
  id: string
}

interface Response {
  __typename: 'User'
  id?: string
}

export function useRemoveUser() {
  return useMutation<Response, Request>(REMOVE_USER_MUTATION, {
    optimisticResponse: (variables: Request): Response => ({
      __typename: 'User',
      ...variables,
    }),
    update: patchQuery<Response[], never, { removeUser: Response }>(
      { query: FETCH_ALL_USERS_QUERY },
      (users, result) => {
        const removedUserId = result?.removeUser?.id
        return users?.filter(store => store.id !== removedUserId) || []
      },
    ),
  })
}

export function App() {
  const [removeUser, { loading, error }] = useRemoveUser()

  const onRemove = useCallback(async () => {
    await removeUser({ id: 'user-id' })
    // do your stuff
  }, [removeUser])

  if (error) {
    return <div className='error'>{error}</div>
  }

  return (
    <button disabled={loading} onClick={onRemove}>
      Remove
    </button>
  )
}

Readme

Keywords

none

Package Sidebar

Install

npm i apollo-react-client

Weekly Downloads

0

Version

0.0.11

License

MIT

Unpacked Size

107 kB

Total Files

32

Last publish

Collaborators

  • rintoj