Drop-in replacements for @apollo/client's useQuery, useMutation and useSubscription hooks with reduced overhead and additional functionality.

Overview

npm version

apollo-augmented-hooks

Drop-in replacements for @apollo/client's useQuery, useMutation and useSubscription hooks with reduced overhead and additional functionality.

What problems does this package solve?

  • It attempts to make complex cache modification as painless as possible by providing additional helpers to cache.modify calls. See this guide on caching for more information.
  • It improves performance by automatically reducing the size of queries sent to the server by stripping all the fields from them that are already in the cache. See this guide on reduced queries for more information.
  • It also improves performance by automatically adding all fields available in the cache to each requested selection, allowing for smaller queries to be written. See this guide on cache inflation for more information.
  • It allows you to globally provide context data for all queries and mutations using a hook.
  • It fixes a race condition causing cache updates with stale data when simultaneously performing mutations and poll requests.

Installation

yarn add apollo-augmented-hooks

or

npm install --save apollo-augmented-hooks

In order to use the hooks, you need to make them aware of your apollo client instance during setup:

import { ApolloClient } from '@apollo/client';
import { initAugmentedHooks } from 'apollo-augmented-hooks';

const client = new ApolloClient();

initAugmentedHooks(client);

API

useQuery

useQuery has the same signature as its @apollo/client counterpart. Additionally, it supports the following new options:

- reducedQuery

Default: true. Set to false if you wish to disable the query reduction functionality. See this guide on reduced queries for more information.

- inflateCacheData

Default: true. Set to false if you wish to disable the cache inflation functionality. See this guide on cache inflation for more information.

- pagination

Experimental and WIP.

useMutation

useMutation has the same signature as its @apollo/client counterpart. However, it does not return a tuple of the mutation function and the mutation result, but just the mutation function, since the result can easily be accessed from the mutation's resolved promise. Additionally, the mutation function supports the following new options:

- input

input can be used in place of the variables option. If the mutation takes only a single argument, input allows the omission of that argument's name. This reduces a bit of overhead with APIs where that is true for the vast majority of mutations.

Example:

With @apollo/client

mutate({
    variables: {
        data: {
            someKey: 'some value'
        }
    }
});

With apollo-augmented-hooks

mutate({
    input: {
        someKey: 'some value'
    }
});

- optimisticResponse

optimisticResponse is already available in the original useMutation, but it now provides a way to reduce some overhead. It automatically adds the attributes from the input object as well as the __typename: 'Mutation' part.

Example:

With @apollo/client

const input = {
    someKey: 'some value',
    someOtherKey: 'some other value'
};

mutate({
    variables: {
        input
    },
    optimisticResponse: {
        __typename: 'Mutation',
        createThing: {
            __typename: 'Thing',
            someKey: 'some value',
            someOtherKey: 'some other value',
            someKeyNotInTheInput: 'foo'
        }
    }
});

With apollo-augmented-hooks

const input = {
    someKey: 'some value',
    someOtherKey: 'some other value'
};

mutate({
    input,
    optimisticResponse: {
        __typename: 'Thing',
        someKeyNotInTheInput: 'foo'
    }
});

- modifiers

modifiers serves as a helper to make cache updates after a mutation as pain-free as possible. It accepts an array of modifiers, and each modifier is either an object supporting the following options or a function returning such an object. See this guide on caching for a more detailed explanation and plenty of examples.

cacheObject

The object that you wish to update in the cache. If you have an object with a __typename and an id property, you can pass it here, and the modifier will use apollo's cache.identify on it so you don't have to. Alternatively you can pass a function returning your cache object. If you do so, the function's single parameter will be the data returned by your mutation, which you can use to determine your cache object.

typename

If you have more than one object to update after your mutation, you can pass a typename, which will cause all objects in your cache with that typename to be modified.

If you pass neither cacheObject nor typename, the modifier will assume ROOT_QUERY.

fields

This works the same as apollo's cache.modify, except that each field function gets passed only the details object. To make cache updating easier, the details object of each field function contains a few additional helpers:

previous

This is what used to be the field function's first parameter, the field's previous value. Since it is often not needed, it is now part of the details object and can simply be ignored.

cacheObject

This is the cache object that you are currently modifying a field on. This helper is especially useful in conjunction with the typename option. See this section in the caching guide for a walk-through of a concrete use case.

item

The data returned by your mutation.

itemRef

The ref object that you should return in your modifier function. Equivalent to cache.toReference(item).

variables

The variables that were used to create the field that you are currently modifying. Its stringified form is already available on details.storeFieldName, but a proper variables object is missing in apollo's implementation.

includeIf

If the field you are modifying is an array, you can call includeIf with a boolean parameter saying whether or not the mutation result should be part of the array. If it is not already part of it but should be, it will be added; if it is already part of it but shouldn't be, it will be removed.

Example:

With @apollo/client

mutate({
    variables: {
        input: someInput
    },
    update: (cache, result) => {
        cache.modify({
            id: cache.identify(someObject),
            fields: {
                things: (previous, { readField, toReference }) => (
                    const next = previous.filter((ref) => details.readField('id', ref) !== item.id);

                    if (includeIf) {
                        next.push(details.toReference(item));
                    }

                    return next;
                ),
            },
        })
    },
});

With apollo-augmented-hooks

mutate({
    input: someInput,
    modifiers: [{
        cacheObject: someObject,
        fields: {
            things: ({ includeIf }) => (
                includeIf(true)
            ),
        },
    }],
});

You can pass a second parameter to includeIf that allows you to specify exactly what subjects you'd like to add to the field (if you don't want to add your mutation's result directly) and what the field's original value should be (if you don't want the field's previous value to be used): includeIf(true, { subjects: [thingA, thingB], origin: [] })

newFields

Sometimes you might want to add fields to cache objects that do not exist yet in order to avoid another server roundtrip to fetch data that your mutation already provides. cache.modify can't do that (as the name suggests, you can only modify existing fields), and cache.writeQuery is very verbose, so newFields provides a compact way to accomplish it. It has essentially the same API as fields, but the only available helpers are cacheObject, item, itemRef and toReference. Since there is no previous data (as we're adding a new field), many of the helpers necessary for fields are obsolete here.

Example for adding the field things to the root query:

mutate({
    input: someInput,
    modifiers: [{
        newFields: {
            things: ({ itemRef }) => itemRef,
        },
    }],
});

If you wish to add a parameterized field to the cache, you can pass the variables like this:

mutate({
    input: someInput,
    modifiers: [{
        newFields: {
            things: {
                variables: { someKey: someValue },
                modify: ({ itemRef }) => itemRef,
            },
        },
    }],
});

The variables attribute also supports a functional notation. Its single parameter is an object containing an item attribute, which is the data returned by your mutation:

mutate({
    input: someInput,
    modifiers: [{
        newFields: {
            things: {
                variables: ({ item }) => ({
                    id: item.id
                }),
                modify: ({ itemRef }) => itemRef,
            },
        },
    }],
});
evict

If the cache object(s) of your modifier should be removed from the cache entirely, simply use evict: true.

- inflateCacheData

Default: true. Set to false if you wish to disable the cache inflation functionality. See this guide on cache inflation for more information.

useSubscription

useSubscription has the same signature as its @apollo/client counterpart. Additionally, it supports the following new options:

- modifiers

Works exactly the same as its useMutation counterpart;

combineResults

If you have more than one instance of useQuery in your hook (e.g. one regular query and one query for polling), you can easily merge their results like this:

export default () => {
    const result = useQuery(...);
    const pollResult = useQuery(...);

    return combineResults(result, pollResult);
};

setGlobalContextHook

WIP

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

Build

npm run build

Test

npm test

License

MIT

Comments
  • Bug: Unable to load any pages of the application

    Bug: Unable to load any pages of the application

    What's happening

    • I run yarn dev and then navigate to the URL
    • Immediately the error happens, nothing loads

    Stacktrace

    ERROR : _document-logger
    message: Cannot read properties of undefined (reading 'value')
    page path: /
    stack trace: TypeError: Cannot read properties of undefined (reading 'value')
        at /Users/adavis/dev/build-meetup/packages/web-next/packages/web/node_modules/apollo-augmented-hooks/lib/helpers/fieldNames.js:39:197
        at Array.reduce (<anonymous>)
        at buildFieldName (/Users/adavis/dev/build-meetup/packages/web-next/packages/web/node_modules/apollo-augmented-hooks/lib/helpers/fieldNames.js:36:34)
        at /Users/adavis/dev/build-meetup/packages/web-next/packages/web/node_modules/apollo-augmented-hooks/lib/helpers/reducedQueries.js:181:52
        at Array.reduce (<anonymous>)
        at makeReducedQueryAst (/Users/adavis/dev/build-meetup/packages/web-next/packages/web/node_modules/apollo-augmented-hooks/lib/helpers/reducedQueries.js:178:68)
        at getQueryAst (/Users/adavis/dev/build-meetup/packages/web-next/packages/web/node_modules/apollo-augmented-hooks/lib/hooks/useReducedQuery.js:35:158)
        at /Users/adavis/dev/build-meetup/packages/web-next/packages/web/node_modules/apollo-augmented-hooks/lib/hooks/useReducedQuery.js:46:12
        at useReducer (/Users/adavis/dev/build-meetup/packages/web-next/packages/web/node_modules/react-dom/cjs/react-dom-server.node.development.js:1537:57)
        at Object.useState (/Users/adavis/dev/build-meetup/packages/web-next/packages/web/node_modules/react-dom/cjs/react-dom-server.node.development.js:1475:10)
    
    opened by adavis 7
  • useQuery hook returns empty data on first render with cache

    useQuery hook returns empty data on first render with cache

    I'm running into a certain behavior that does not appear to be intentional. The scenario is that I have a list of events that are fetched with useQuery. For this example, the events are already in the cache.

    Here is the result of me logging the 'data' and 'loading' params on the first two renders:

    Render 1:
    Loading? true
    Events:  null
    
    Render 2:
    Loading? false
    Events:  {energyEvents: Array(12)}
    

    If I swap out apollo-augmented-hooks for apollo/client, it looks like this:

    Render 1:
    Loading? false
    Events:  {energyEvents: Array(12)}
    
    Render 2:
    Loading? false
    Events:  {energyEvents: Array(12)}
    

    Here's my call to useQuery:

    const { data: energyEventsData, loading: energyEventsLoading, refetch: refetchEnergyEvents } = useQuery<GetEnergyEventsResponse>(GetEnergyEventsQuery, {
            fetchPolicy: 'cache-first',
            reducedQuery: false,
            pollInterval: getApiPollInterval(),
            variables: {
                interval: 'ALL',
            },
        });
    
        console.log('Loading? ' + energyEventsLoading)
        console.log('Events: ', energyEventsData);
    
    opened by iankberry 7
  • Cannot read property 'filter' of undefined

    Cannot read property 'filter' of undefined

    I've just begun to experiment with switching over from @apollo/client. I've changed useQuery across and am getting Cannot read property 'filter' of undefined.

    variableDefinitions: definition.variableDefinitions.filter(function (_ref3) {
    
    reducedQueries.js (231.28)
    
    opened by alexpchin 5
  • `cacheObject` with fields using customized cache IDs not updating

    `cacheObject` with fields using customized cache IDs not updating

    It seems like apollo-augmented-hooks/useMutation isn't able to update a cacheObject with fields who have customized cache IDs. In this case, ProductInBag has a custom cache ID derived from selectedOption.id, it's not removed from bag when using includeIf(false).

    type Bag {
        id: Int
        products: [ProductInBag]
    }
    ...
    new InMemoryCache({
        typePolicies: {
          ProductInBag: {
            keyFields: ['selectedOption', ['id']]
          }
      }
    })
    ...
    const DELETE_PRODUCT_FROM_BAG = gql`
      mutation DeleteProductFromBag($selectedOptionId: Int!) {
        deleteProductFromBag(selectedOptionId: $selectedOptionId) {
          selectedOption {
            id
          }
        }
      }
    `
    ...
    const deleteProductFromBagMutation = useMutation(DELETE_PRODUCT_FROM_BAG)
    
    const handleOnPressDelete = async (selectedOption) => {
      await deleteProductFromBagMutation({
        variables: {
          selectedOptionId: selectedOption.id
        },
        modifiers: [{
          cacheObject: bag,
          fields: {
            products: ({ includeIf }) => includeIf(false) // this is not removing the deleted ProductInBag, even though it is returned from mutation
          }
        }]
      })
    }
    
    opened by jsindos 4
  • Re-Export `useLazyQuery`

    Re-Export `useLazyQuery`

    When a project uses useLazyQuery, it currently has to import it from @apollo/client. Does it make sense to re-export it from apollo-augmented-hooks to avoid multiple import statements?

    opened by garritfra 3
  • Reason to use writeFragment instead of toReference

    Reason to use writeFragment instead of toReference

    This is just a remark:

    I was looking in the documentation where it says:

    The modifier function's second parameter includes an undocumented helper function called toReference, which essentially does the same thing as the entire cache.writeFragment block above. It's much easier to use and produces cleaner and more maintainable code. I am not aware of any reason to use cache.writeFragment in favour of this.

    But there is actually a reason to use writeFragment. The problem is that toReference will only deal with scalars. So if you have any custom types (e.g. dates), these will not end up correctly in the cache. writeFragment, although way more verbose, does take care of that. This is explained by an Apollo dev a bit more extensive here: https://github.com/apollographql/apollo-client/pull/6289#issuecomment-630925056

    opened by sebakerckhof 3
  • Unnecessary re-fetching of queries when using modifiers

    Unnecessary re-fetching of queries when using modifiers

    Hi! First of all thanks for the great package, I like its concise syntax over Apollo's verbosity. The only problem I've run into is unnecessary re-fetching of queries which I describe below.

    Description of app

    My app has types Product and Wishlist. Wishlist has a products field. When I first start up the app, I query for a product and wishlists. No wishlists yet exist in the app.

    Product:1:
      id: 1
      wishlist: null
    ROOT_QUERY:
      wishlists: []
      product({"id":1}): {__ref: 'Product:1'}
    

    I call the following mutation which creates a wishlist and adds a product to it, with productId=1. This mutation returns the created wishlist:

    mutation CreateWishlist($name: String!, $productId: Int!) {
      createWishlist(name: $name, productId: $productId) {
        id
        products {
          id
        }
      }
    }
    ...
    await createWishlistMutation({
      variables: {
        name: listName,
        productId
      }
    })
    

    This successfully creates the wishlist in the cache, but doesn't update ROOT_QUERY.wishlists or Product:1.wishlist:

    Product:1:
      id: 1
      wishlist: null
    ROOT_QUERY:
      wishlists: []
      product({"id":1}): {__ref: 'Product:1'}
    Wishlist:2:
      id: 2
      products: Array(1)
        0: {__ref: 'Product:1'}
    

    Using apollo-augmented-hooks

    I call the createWishlist mutation using apollo-augmented-hooks with two modifiers:

    await createWishlistMutation({
      variables: {
        name: listName,
        productId
      },
      modifiers: [{
        fields: {
          wishlists: ({ includeIf }) => {
            return includeIf(true)
          }
        }
      }, {
        cacheObject: { id: productId, __typename: 'Product' },
        fields: {
          wishlist: ({ item }) => item
        }
      }]
    })
    

    This successfully updates the cache (as intended):

    Product:1:
      id: 1
      wishlist: {__typename: 'Wishlist', id: 3, products: Array(1)}
    ROOT_QUERY:
      wishlists: Array(1)
        0: {__ref: 'Wishlist:3'}
      product({"id":1}): {__ref: 'Product:1'}
    Wishlist:3:
      id: 3
      products: Array(1)
        0: {__ref: 'Product:1'}
    

    All was working fine, however I realised adding the modifiers caused Apollo to re-fetch the query which initially populates the wishlists:

    query {
      wishlists {
        id
        featuredImage
        name
      }
    }
    

    Here is Chrome network tab, this bottom request is only sent if I include the above modifiers:

    image

    I don't understand why Apollo does a re-fetch, as I was under the impression apollo-augmented-hooks uses cache.modify internally, which should keep everything local? I'll keep digging into this.

    opened by jsindos 3
  • Modify object before saving to cache?

    Modify object before saving to cache?

    First of all, thanks for the great library! I'm impressed how well thought out it is at such an early stage.

    I'm struggling to do something that I have previously used cache.writeFragment() for. Basically, I have a mutation that returns an object to save to the cache except for a specific property that I would like to override locally before saving to the cache. Basically some additional local state the server is unaware of. Using every method I have tried reading the docs, the originally unaltered mutation response is being saved to the cache, even though the fields modifier is correctly adding it to the list (the events query).

    Here is an example that works as expected:

    mutation({
        variables: {
            someField: 'value'
        },
        update: (cache, result) => {
            const { data: { createEvent } } = result;
            cache.writeFragment({
                id: cache.identify(createEvent),
                fragment: EventFragment,
                data: {
                    ...createEvent,
                    score: 10
                },
            });
        },
        modifiers: [{
            fields: {
                events: ({ includeIf }) => includeIf(true)
            }
        }],
    });
    

    Here is an example that does not work, where the score saved to the cache has the value from the API, not the value specified here. Perhaps I am not understanding how cacheObject is supposed to be used?

    mutation({
        variables: {
            someField: 'value'
        },
        modifiers: [{
            cacheObject: item => {
                return {
                    ...item,
                    score: 10,
                }
            },
            fields: {
                events: ({ includeIf }) => includeIf(true)
            }
        }],
    });
    

    Thanks in advance for your help!

    opened by iankberry 3
  • Uncaught ReferenceError: regeneratorRuntime is not defined

    Uncaught ReferenceError: regeneratorRuntime is not defined

    Hi, so I've been experimenting around with migrating my hooks to this package but I have this error thrown in my browser console whenever I try to execute a mutation.

    I'm using a Meteor/Apollo stack so my client code is as follows:

    import React from "react"
    import { Meteor } from "meteor/meteor"
    import { render } from "react-dom"
    import { BrowserRouter } from "react-router-dom"
    import { ApolloClient, HttpLink, split, InMemoryCache, ApolloProvider } from "@apollo/client"
    import { ApolloLink, from } from "apollo-link"
    
    import { DDPSubscriptionLink, isSubscription } from 'apollo-link-ddp'
    import { offsetLimitPagination } from "@apollo/client/utilities"
    import { initAugmentedHooks } from "apollo-augmented-hooks"
    import App from "../../ui/App"
    
    const httpLink = new HttpLink({ uri: "http://XXX.XXX.XX.XX:3000/graphql" })
    
    const authLink = new ApolloLink((operation, forward) => {
        const token = Accounts._storedLoginToken()
        operation.setContext(() => ({
            headers: {
                authorization: token
            }
        }))
        return forward(operation)
    })
    
    const subscriptionLink = new DDPSubscriptionLink()
    
    const splitLink = split(
        isSubscription,
        subscriptionLink,
        httpLink
    )
    
    const cache = new InMemoryCache({
        typePolicies: {
            Query: {
                fields: {
                    getFeed: offsetLimitPagination()
                }
            }
        }
    })
    
    const client = new ApolloClient({
        link: from([authLink, splitLink]),
        cache
    })
    
    initAugmentedHooks(client)
    
    const ApolloApp = () => (
        <BrowserRouter>
            <ApolloProvider client={client}>
                <App client={client} />
            </ApolloProvider>
        </BrowserRouter>
    )
    
    Meteor.startup(() => {
        render(<ApolloApp />, document.getElementById("app"))
    })
    

    And my mutation is merely as follows:

    const EDIT_THING = gql`
        mutation EditThing($someInt: Int!) {
            editThing(someInt: $someInt)
        }
    `
    

    Initialized as such:

    import { useMutation } from "apollo-augmented-hooks"
    import { gql } from "@apollo/client"
    const sendMutation = useMutation(EDIT_THING)
    

    Further in my component I have:

    sendMutation({ variables: { someInt: IntFromComponent }})
    

    But this throws Uncaught ReferenceError: regeneratorRuntime is not defined in my console for some reason. I'm using the latest release, 1.8.0. Have also tried removing the package and re-installing it to no avail.

    opened by ajaypillay 3
  • Children of the same type down the tree not inflated

    Children of the same type down the tree not inflated

    This is a followup issue of the fix added in 1d1e0f104e2727c309d0c56d00ce7f67666e6b9f.

    The fix works for direct parent/children relations, but not for objects of the same type deeper down the tree.

    Failing Test Case

    it('works with child data of the same type down the tree', () => {
        const query = gql`
            query {
                todos {
                    id
                    title
                    assignee {
                        id
                        assignedTodos {
                            id
                            title
                        }
                    }
                }
            }
        `;
        const data = {
            todos: [{
                __typename: 'Todo',
                id: 'some-id',
                title: 'Do the dishes',
                assignee: [{
                    __typename: 'Person',
                    id: 'alice',
                    assignedTodos: [{
                        __typename: 'Todo',
                        id: 'some-id',
                        title: 'Do the dishes',
                    }],
                }],
            }],
        };
    
        cache.writeQuery({ query, data });
    
        const inflatedData = inflateCacheData(cache, cache.readQuery({ query }));
    
        expect(inflatedData).toEqual(data);
    });
    
    opened by garritfra 2
  • Cache corruption issue with useQuery

    Cache corruption issue with useQuery

    I've got another strange issue where the cached data coming back from useQuery is slightly corrupted. It's the same query that I was referencing in #6.

    Here is what the data looks like when using the stock @apollo/client version of useQuery:

    {
      "selectedEnergyEvent": {
        "__typename": "EnergyEvent",
        "id": "8357862188871433499",
        "time": "2021-07-28T18:39:08-04:00",
        "startTime": "2021-07-28T14:34:31-04:00",
        "endTime": "2021-07-28T18:39:08-04:00",
        "energyType": "DRAIN",
        "algorithm": "WORK_TIME",
        "algorithmData": null,
        "context": [
          {
            "__typename": "EnergyActivityContext",
            "contextType": "ACTIVITY",
            "activity": {
              "__typename": "ActivitySlice",
              "id": "6100042703173699744",
              "providerId": "504326868638495413",
              "providerType": "GOOGLE",
              "providerGroupName": "Default",
              "startTime": "2021-07-28T14:34:31-04:00",
              "endTime": "2021-07-28T14:38:32-04:00",
              "activityType": "APP",
              "activityGroup": "iTerm",
              "activityCount": 2,
              "audience": "INDIVIDUAL",
              "categories": [
                "WORKGROUP_ACCOUNT"
              ],
              "participants": [],
              "energyType": "NONE",
              "vendorUrl": null
            }
          }
        ]
      }
    }
    

    And the exact same query with apollo-augmented-hooks:

    {
      "selectedEnergyEvent": {
        "id": "8357862188871433499",
        "__typename": "EnergyEvent",
        "time": "2021-07-28T18:39:08-04:00",
        "startTime": "2021-07-28T14:34:31-04:00",
        "endTime": "2021-07-28T18:39:08-04:00",
        "energyType": "DRAIN",
        "algorithm": "WORK_TIME",
        "algorithmData": null,
        "context": [
          {
            "__typename": "EnergyActivityContext",
            "contextType": "ACTIVITY",
            "activity": {
              "id": "6100042703173699744",
              "__typename": "ActivitySlice",
              "providerId": "504326868638495413",
              "providerType": "GOOGLE",
              "providerGroupName": "Default",
              "startTime": "2021-07-28T14:34:31-04:00",
              "endTime": "2021-07-28T14:38:32-04:00",
              "activityType": "APP",
              "activityGroup": "iTerm",
              "activityCount": 2,
              "audience": "INDIVIDUAL",
              "categories": [
                {
                  "0": "W",
                  "1": "O",
                  "2": "R",
                  "3": "K",
                  "4": "G",
                  "5": "R",
                  "6": "O",
                  "7": "U",
                  "8": "P",
                  "9": "_",
                  "10": "A",
                  "11": "C",
                  "12": "C",
                  "13": "O",
                  "14": "U",
                  "15": "N",
                  "16": "T"
                }
              ],
              "participants": [],
              "energyType": "NONE",
              "vendorUrl": null
            }
          }
        ]
      }
    }
    

    Possible relevant, I am using the apollo-cache-persist library to persist my Apollo cache to localstorage. If I look at the data in localstorage directly, it is correctly formatted though.

    If I had to guess, it looks like a possible issue with the spread operator on a nested array but you'd know better than me :-)

    opened by iankberry 2
Releases(v3.1.1)
  • v3.1.1(Apr 25, 2022)

  • v3.1.0(Apr 22, 2022)

    Features

    • Add modifiers option to useLazyQuery hook.
    • Make useLazyQuery hook aware of the global context hook.

    Fixes

    • Make reduced queries work with fields using the @client directive.

    Documentation

    • Add a section on how to use setGlobalContextHook.
    Source code(tar.gz)
    Source code(zip)
  • v3.0.3(Apr 22, 2022)

  • v3.0.2(Apr 21, 2022)

  • v3.0.1(Apr 20, 2022)

  • v3.0.0(Apr 19, 2022)

    Breaking changes

    No new features for this release, but I'm undoing a decision I've made back when I first wrote this package. At the time, I'd decided to only return the mutate function from the useMutation hook and not the entire tuple. The reason for this was that I was under the impression that you could just as easily access the mutation's loading and error states from the mutate function itself. While this is true, I've come to realise that there can be situations where it is much more convenient to access these states from the useMutation tuple instead. That's why I've made the decision to expose the tuple from this point forward, which is unfortunately a breaking change.

    If you've been using v2.x.x of apollo-augmented-hooks, here is how to migrate to v3.0.0. Replace any calls to useMutation as follows:

    // old
    const mutate = useMutation();
    
    // new
    const [mutate] = useMutation();
    
    Source code(tar.gz)
    Source code(zip)
  • v2.2.0(Apr 1, 2022)

  • v2.1.3(Nov 29, 2021)

  • v2.1.2(Nov 29, 2021)

  • v2.1.1(Oct 19, 2021)

  • v2.1.0(Sep 15, 2021)

  • v2.0.0(Sep 2, 2021)

  • v1.13.13(Sep 1, 2021)

    Fixes

    • Revert cache inflation infinite loop detection back to typenames but orient by sub path duplicates instead.
    • Fix cache inflation performance drop.
    Source code(tar.gz)
    Source code(zip)
  • v1.13.8(Aug 31, 2021)

  • v1.13.7(Aug 31, 2021)

  • v1.13.6(Aug 31, 2021)

    Fixes

    • Fix cache inflation for fields with aliases.
    • Improve cache inflation's infinite loop detection by using the cache key rather than typename paths.
    Source code(tar.gz)
    Source code(zip)
  • v1.13.5(Aug 23, 2021)

  • v1.13.4(Aug 12, 2021)

  • v1.13.3(Aug 11, 2021)

  • v1.13.2(Aug 11, 2021)

  • v1.13.1(Aug 11, 2021)

  • v1.13.0(Aug 11, 2021)

    Features

    • Allow functional modifiers in addition to objects. Functional modifiers can be used for mutations that return arrays. If a function is used, the function will be called once for each item in the mutation's result array.
    • Allow passing subjects and origin to includeIf. If passed, subjects will be used instead of item and origin instead of previous, allowing for greater control over includeIf's behavior.
    Source code(tar.gz)
    Source code(zip)
  • v1.12.0(Aug 11, 2021)

    Features

    • Apply cache inflation logic to useMutation hook. This causes the data returned by a mutation to be enriched with matching data found in the cache, mimicking the behavior already implemented in useQuery. Allow users to disable this feature by setting inflateCacheData: false in the useMutation options.
    Source code(tar.gz)
    Source code(zip)
  • v1.11.6(Aug 5, 2021)

  • v1.11.5(Aug 4, 2021)

  • v1.11.4(Jul 30, 2021)

  • v1.11.3(Jul 22, 2021)

  • v1.11.2(Jul 21, 2021)

    Fixes

    • Remove unnecessary and undocumented behaviour that caused queries with poll intervals to always make an initial network request on component mount.
    Source code(tar.gz)
    Source code(zip)
  • v1.11.1(Jul 8, 2021)

  • v1.11.0(Jul 8, 2021)

    Features

    • Allow a functional notation for the modifiers -> newFields -> variables option so the server response can be leveraged to build the new field's variables.
    Source code(tar.gz)
    Source code(zip)
Owner
appmotion Devs
appmotion Devs
Windows notepad in web with additional features! Made with typescript and react.

Notepad Windows notepad in web with additional features! ?? Table of Contents ?? About Why I created ? Helpful for ? Who can contribute ? ?? Getting S

Muhammed Rahif 22 Jan 3, 2023
A simple and responsive quizlet-like flashcard component with a few additional options

Welcome to react-quizlet-flashcard ?? A simple and responsive quizlet-like flashcard component with a few additional options. Front and back card acce

A.B.Santhosh 14 Dec 17, 2022
This repo is for educational and demonstration purposes only, this project is to demonstrate usage of apollo/client and github API and firebase.

Gissues Gissues is a web application that allows you to search for issues in GitHub. It is built for new developers who want to learn more about GitHu

Shikhar 10 Oct 1, 2022
Beautiful and accessible drag and drop for lists with React

react-beautiful-dnd (rbd) Beautiful and accessible drag and drop for lists with React Play with this example if you want! Core characteristics Beautif

Atlassian 28.9k Jan 7, 2023
⚛️ Hooks for building fast and extendable tables and datagrids for React

Hooks for building lightweight, fast and extendable datagrids for React Enjoy this library? Try them all! React Query, React Form, React Charts Visit

Tanner Linsley 20.3k Jan 3, 2023
Fast, tiny and solid hooks system for Javascript and Node.js

Uncino ?? Fast, tiny and solid hooks system for Javascript and NodeJS Uncino is italian word for hook Do you know Wordpress hooks system? Uncino is a

Riccardo Tartaglia 201 Dec 7, 2022
⚛️ Hooks for fetching, caching and updating asynchronous data in React

Hooks for fetching, caching and updating asynchronous data in React Enjoy this library? Try the entire TanStack! React Table, React Form, React Charts

Tanner Linsley 32.1k Jan 9, 2023
Drag and Drop for React

React DnD Drag and Drop for React. See the docs, tutorials and examples on the website: http://react-dnd.github.io/react-dnd/ See the changelog on the

React DnD 18.7k Jan 9, 2023
Fully typed hooks and utility functions for the React Native StyleSheet API

react-native-style-utilities Fully typed hooks and utility functions for the React Native StyleSheet API npm i react-native-style-utilities ESLint Set

Marc Rousavy 73 Dec 17, 2022
Built a covid-19 trcaker app using React.js implementing hooks and materail UI

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

Aditya Dond 1 Dec 21, 2021
Add multiplayer presence (live cursors/avatars) to your react application using yjs and hooks

y-presence Easy way to add presence (live cursors/avatars) to any react application using react hooks. Installation yarn add y-presence # or npm i y-p

Nimesh Nayaju 126 Dec 29, 2022
preact.js with hooks and ES2021, without compilers

naked preact preact.js with hooks, without compilers Web development should be simple. No compilers, just ES2021 and preact+hooks. See comments in the

Oleksandr Nikitin 3 Jun 16, 2022
React components and hooks for creating VR/AR applications with @react-three/fiber

@react-three/xr React components and hooks for creating VR/AR applications with @react-three/fiber npm install @react-three/xr These demos are real,

Poimandres 1.4k Jan 4, 2023
A npm package to increase the developer experience and consistency by providing a set of hooks that can be opted-in the development lifecycle.

@jeliasson/husky-hooks This npm package aims to increase the developer experience and consistency by providing a set of hooks that can be opted-in the

Johan Eliasson 8 Dec 6, 2022
React Hooks — 👍

Collaborative editing for your app. Support on Kickstarter! ?? react-use Collection of essential React Hooks. Port of libreact. Translations: ???? 汉语

Vadim Dalecky 34.9k Jan 3, 2023
📋 React Hooks for forms validation (Web + React Native)

English | 繁中 | 简中 | 日本語 | 한국어 | Français | Italiano | Português | Español | Русский | Deutsch | Türkçe Features Built with performance and DX in mind

React Hook Form 32.4k Dec 29, 2022
React Hooks library for remote data fetching

Introduction swr.vercel.app SWR is a React Hooks library for remote data fetching. The name “SWR” is derived from stale-while-revalidate, a cache inva

Vercel 25.2k Jan 4, 2023
Redux-Toolkit example with React Hooks CRUD Application, Axios, Rest API, Bootstrap

Redux-Toolkit CRUD example with React Hooks, Axios & Web API Build Redux-Toolkit CRUD application with React Hooks and Rest API calls in that: Each it

null 69 Dec 27, 2022
React Hooks tutorial for beginners.

React Hooks for Beginners git clone <url> Clone into the repo code react-hooks Open the folder in VS Code npm install Install the dependencies npm sta

Mohammad Muazam 2 Oct 10, 2022