graasp / graasp-query-client

GNU Affero General Public License v3.0
1 stars 0 forks source link

chore(deps): migrates TanStack Query to v5 #892

Open ReidyT opened 3 weeks ago

ReidyT commented 3 weeks ago

TanStack Query v5 has removed the onSuccess of useQuery. It seems that we are using it to manipulate the cache, so for now, I implemented a function that should work the same way. The onError is also removed, apparently we have to use a query cache for that...

For more informations, check this link: https://tkdodo.eu/blog/breaking-react-querys-api-on-purpose.

ReidyT commented 2 weeks ago

Just below is a diagram describing the behaviour of all the useQuery using onSuccess. I also include some useQuery which are the "default" queries for some cache, to have a better understanding of where and why some cache are manipulated manually. With this diagram, we could maybe reorganise our cache or the way we use query client.

graph LR
    subgraph "useMembers Hook (deprecated?)"
        UseMembers["useQuery \n queryKey: memberKeys.many(ids)"] --> UseMembersSuccess
        UseMembersSuccess["onSuccess Callback"] --> IterateMembersData{Iterate over members.data}
        IterateMembersData -- member --> SetMemberData["queryClient.setQueryData()"]
    end
    SetMemberData --> MemberCache["Cache: memberKeys.single(id).content"]

    subgraph "useMember Hook (B)"
        UseMember["useQuery \n queryKey: memberKeys.single(id).content"] --> MemberCache
    end

    subgraph "useManyItemPublishedInformations Hook (B)"
        UseManyItemPublishedInfo["useQuery \n queryKey: itemKeys.many(args.itemIds).publishedInformation"] --> UseManyItemPublishedInfoSuccess
        UseManyItemPublishedInfoSuccess["onSuccess Callback"] --> IteratePublishedData{Iterate over publishedData.data}
        IteratePublishedData -- publishedInformation --> SetPublishedData["queryClient.setQueryData()"]
    end
    SetPublishedData --> PublishedInfoCache["Cache: itemKeys.single(id).publishedInformation"]

    subgraph "useItemPublishedInformation Hook (B)"
        UseItemPublishedInfo["useQuery \n queryKey: itemKeys.single(args.itemId).publishedInformation"] --> PublishedInfoCache
    end

    subgraph "useItemsTags Hook (deprecated?)"
        UseItemsTags["useQuery \n queryKey: itemKeys.many(ids).tags"] --> UseItemsTagsSuccess
        UseItemsTagsSuccess["onSuccess Callback"] --> IterateItemIds{Iterate over ids}
        IterateItemIds -- id --> GetItemTagFromData{Get item tag from data by id} -- itemTag --> SetTagsData["queryClient.setQueryData()"]
    end
    SetTagsData --> TagsCache["Cache: itemKeys.single(id).tags"]

    subgraph "useItemTags Hook (L)"
        UseItemTags["useQuery \n queryKey: itemKeys.single(id).tags"] --> TagsCache
    end

    subgraph "useManyItemMemberships Hook (deprecated?)"
        UseManyItemMemberships["useQuery \n queryKey: buildManyItemMembershipsKey(ids)"] --> UseManyItemMembershipsSuccess
        UseManyItemMembershipsSuccess["onSuccess Callback"] --> IterateMembershipIds{Iterate over ids}
        IterateMembershipIds -- id --> GetMembershipFromData{Get membership from data by id} -- membership --> SetMembershipsData["queryClient.setQueryData()"]
    end
    SetMembershipsData --> MembershipsCache["Cache: itemKeys.single(id).memberships"]

    subgraph "useItemMemberships Hook (B & P)"
        UseItemMemberships["useQuery \n queryKey: itemKeys.single(id).memberships"] --> MembershipsCache
    end

    subgraph "useDescendants Hook (P)"
      UseDescendants["useQuery \n queryKey: itemKeys.single(id).descendants(...)"] --> UseDescendantsSuccess
      UseDescendantsSuccess["onSuccess Callback"] --> IterateDescendantItems{Iterate over items}
      IterateDescendantItems -- item --> SetDescendantsData["queryClient.setQueryData()"]
      SetDescendantsData --> ItemSingleContentCache["Cache: itemKeys.single(id).content"]
    end

    subgraph "useAccessibleItems Hook (B & P)"
      UseAccessibleItems["useQuery \n queryKey: itemKeys.accessiblePage(...)"] --> UseAccessibleItemsSuccess
      UseAccessibleItemsSuccess["onSuccess Callback"] --> IterateAccessibleItems{Iterate over items}
      IterateAccessibleItems -- item --> SetAccessibleData["queryClient.setQueryData()"]
      SetAccessibleData --> ItemSingleContentCache["Cache: itemKeys.single(id).content"]
    end

    subgraph "useInfiniteAccessibleItems Hook (B)"
      UseInfiniteAccessibleItems["useInfiniteQuery \n queryKey: itemKeys.infiniteAccessible(...)"] --> UseInfiniteAccessibleItemsSuccess
      UseInfiniteAccessibleItemsSuccess["onSuccess Callback"] --> IteratePages{Iterate over pages}
      IteratePages -- page --> IterateAccessibleItemsFromPage{Iterate over items}
      IterateAccessibleItemsFromPage -- item --> SetInfiniteAccessibleData["queryClient.setQueryData()"]
      SetInfiniteAccessibleData --> ItemSingleContentCache["Cache: itemKeys.single(id).content"]
    end

    subgraph "useChildren Hook (B & P)"
      UseChildren["useQuery \n queryKey: itemKeys.single(id).children(...)"] --> UseChildrenSuccess
      UseChildrenSuccess["onSuccess Callback"] --> IterateChildrenItems{Iterate over items}
      IterateChildrenItems -- item --> SetChildrenData["queryClient.setQueryData()"]
      SetChildrenData --> ItemSingleContentCache["Cache: itemKeys.single(id).content"]
    end

    subgraph "useParents Hook (B)"
      UseParents["useQuery \n queryKey: itemKeys.single(id).parents"] --> UseParentsSuccess
      UseParentsSuccess["onSuccess Callback"] --> IterateParentsItems{Iterate over items}
      IterateParentsItems -- item --> SetParentsData["queryClient.setQueryData()"]
      SetParentsData --> ItemSingleContentCache["Cache: itemKeys.single(id).content"]
    end

    subgraph "useItems Hook (B)"
      UseItems["useQuery \n queryKey: itemKeys.many(ids).content"] --> UseItemsSuccess
      UseItemsSuccess["onSuccess Callback"] --> IterateItemsData{Iterate over items.data}
      IterateItemsData -- item --> SetItemsData["queryClient.setQueryData()"]
      SetItemsData --> ItemSingleContentCache["Cache: itemKeys.single(id).content"]
    end

    subgraph "useRecycledItemsData Hook (deprecated?)"
      UseRecycledItemsData["useQuery \n queryKey: memberKeys.current().recycled"] --> UseRecycledItemsDataSuccess
      UseRecycledItemsDataSuccess["onSuccess Callback"] --> IterateRecycledItemsData{Iterate over items}
      IterateRecycledItemsData -- item --> SetRecycledItemsData["queryClient.setQueryData()"]
      SetRecycledItemsData --> ItemSingleContentCache["Cache: itemKeys.single(id).content"]
    end

    style UseMembersSuccess fill:#f9f,stroke:#333,stroke-width:2px,color:#000
    style IterateMembersData fill:#ccf,stroke:#333,stroke-width:2px,color:#000
    style SetMemberData fill:#9cf,stroke:#333,stroke-width:2px,color:#000
    style MemberCache fill:#ff9,stroke:#333,stroke-width:2px,color:#000
    style UseMember fill:#aaf,stroke:#333,stroke-width:2px,color:#000
    style UseMembers fill:#8B0000,stroke:red,stroke-width:2px,color:white
    style UseManyItemPublishedInfoSuccess fill:#f9f,stroke:#333,stroke-width:2px,color:#000
    style IteratePublishedData fill:#ccf,stroke:#333,stroke-width:2px,color:#000
    style SetPublishedData fill:#9cf,stroke:#333,stroke-width:2px,color:#000
    style PublishedInfoCache fill:#ff9,stroke:#333,stroke-width:2px,color:#000
    style UseItemPublishedInfo fill:#aaf,stroke:#333,stroke-width:2px,color:#000
    style UseManyItemPublishedInfo fill:#aaf,stroke:#333,stroke-width:2px,color:#000
    style UseItemsTags fill:#8B0000,stroke:red,stroke-width:2px,color:white
    style UseItemsTagsSuccess fill:#f9f,stroke:#333,stroke-width:2px,color:#000
    style IterateItemIds fill:#ccf,stroke:#333,stroke-width:2px,color:#000
    style GetItemTagFromData fill:#ccf,stroke:#333,stroke-width:2px,color:#000
    style SetTagsData fill:#9cf,stroke:#333,stroke-width:2px,color:#000
    style TagsCache fill:#ff9,stroke:#333,stroke-width:2px,color:#000
    style UseItemTags fill:#aaf,stroke:#333,stroke-width:2px,color:#000
    style UseManyItemMemberships fill:#8B0000,stroke:red,stroke-width:2px,color:white
    style UseManyItemMembershipsSuccess fill:#f9f,stroke:#333,stroke-width:2px,color:#000
    style IterateMembershipIds fill:#ccf,stroke:#333,stroke-width:2px,color:#000
    style GetMembershipFromData fill:#ccf,stroke:#333,stroke-width:2px,color:#000
    style SetMembershipsData fill:#9cf,stroke:#333,stroke-width:2px,color:#000
    style MembershipsCache fill:#ff9,stroke:#333,stroke-width:2px,color:#000
    style UseItemMemberships fill:#aaf,stroke:#333,stroke-width:2px,color:#000
    style UseDescendants fill:#aaf,stroke:#333,stroke-width:2px,color:#000
    style UseDescendantsSuccess fill:#f9f,stroke:#333,stroke-width:2px,color:#000
    style IterateDescendantItems fill:#ccf,stroke:#333,stroke-width:2px,color:#000
    style ItemSingleContentCache fill:#ff9,stroke:#333,stroke-width:2px,color:#000
    style UseAccessibleItems fill:#aaf,stroke:#333,stroke-width:2px,color:#000
    style UseAccessibleItemsSuccess fill:#f9f,stroke:#333,stroke-width:2px,color:#000
    style IterateAccessibleItems fill:#ccf,stroke:#333,stroke-width:2px,color:#000
    style UseInfiniteAccessibleItems fill:#aaf,stroke:#333,stroke-width:2px,color:#000
    style UseInfiniteAccessibleItemsSuccess fill:#f9f,stroke:#333,stroke-width:2px,color:#000
    style IteratePages fill:#ccf,stroke:#333,stroke-width:2px,color:#000
    style IterateAccessibleItemsFromPage fill:#ccf,stroke:#333,stroke-width:2px,color:#000
    style SetDescendantsData fill:#9cf,stroke:#333,stroke-width:2px,color:#000
    style SetAccessibleData fill:#9cf,stroke:#333,stroke-width:2px,color:#000
    style SetInfiniteAccessibleData fill:#9cf,stroke:#333,stroke-width:2px,color:#000
    style UseChildren fill:#aaf,stroke:#333,stroke-width:2px,color:#000
    style UseChildrenSuccess fill:#f9f,stroke:#333,stroke-width:2px,color:#000
    style IterateChildrenItems fill:#ccf,stroke:#333,stroke-width:2px,color:#000
    style SetChildrenData fill:#9cf,stroke:#333,stroke-width:2px,color:#000
    style UseParents fill:#aaf,stroke:#333,stroke-width:2px,color:#000
    style UseParentsSuccess fill:#f9f,stroke:#333,stroke-width:2px,color:#000
    style IterateParentsItems fill:#ccf,stroke:#333,stroke-width:2px,color:#000
    style SetParentsData fill:#9cf,stroke:#333,stroke-width:2px,color:#000
    style UseItems fill:#aaf,stroke:#333,stroke-width:2px,color:#000
    style UseItemsSuccess fill:#f9f,stroke:#333,stroke-width:2px,color:#000
    style IterateItemsData fill:#ccf,stroke:#333,stroke-width:2px,color:#000
    style SetItemsData fill:#9cf,stroke:#333,stroke-width:2px,color:#000
    style UseRecycledItemsData fill:#8B0000,stroke:red,stroke-width:2px,color:white
    style UseRecycledItemsDataSuccess fill:#f9f,stroke:#333,stroke-width:2px,color:#000
    style IterateRecycledItemsData fill:#ccf,stroke:#333,stroke-width:2px,color:#000
    style SetRecycledItemsData fill:#9cf,stroke:#333,stroke-width:2px,color:#000
ReidyT commented 2 weeks ago

As we discussed this morning, we have to check that there is no performance drawbacks, but we'll probably be able to remove the setQueryData from the useQuery.

ReidyT commented 1 day ago

Also, we can use the data from the cache of the many queries in the placeholder of single query as described in tanstack query docs: placeholder-data-from-cache or maybe initialData placeholder vs initial data.

But I don't think we really need it!

sonarcloud[bot] commented 1 day ago

Quality Gate Passed Quality Gate passed

Issues
0 New issues
0 Accepted issues

Measures
0 Security Hotspots
0.0% Coverage on New Code
4.2% Duplication on New Code

See analysis details on SonarCloud