How to paginate unpaginated data with SWR - reactjs

Let's say you have some data that is fetched from an api. It all comes in in one chunk, unpaginated. I am using vercel's SWR library. Is there a way to paginate this data client-side? useSWRInfinite relies on the fact that the link that you provide to it will have the ?page={pageNumber} query.

Not sure if I understood you correctly, but if you have unpaginated data when the request is done, do you mean that you have all the data from the API?
If that is the case, why don't you just write the pagination logic?
So you are already holding all the data in some variable I assume, use that data to create pagination. Create the state variable and just do the math so its value changes based on the selected page, there are multiple examples of that.

Related

Redux Tool Kit Query: Need same data in different two components but without duplicate requests

I'm new to rtk and rtk query , I'm using rtk query. I have two components I need the same data for each, I do not want to call the function twice in each component to get the same data, is there a way to only call it one time then for better performance?
for example
I'm calling getCartItems in one of those components but I need the same data in the nav bar component to get its count
so I don't want to send the same request again am I right ?
When you query data, redux toolkit query will store those queries inside queries of slice in the redux store:
this is stored in the global state, so anytime you make a request to an endpoint, rtk query first checks this property and if there is same query, it does not add a new query, it de-duplicates (eliminates duplicate) and returns the result of the original query
If you call the same query hook with the same argument in multiple components, only one request will be made. Cache entries are shared internally, that's pretty much the point of RTK Query.
Try it out & take a look at your network devtools :)

React- Storing in context or make API calls which one is better

In React, when you have to display data in select box for users to multiselect(using material ui auto complete). Total records count is approximately like 6ooo+. Saving it in context is efficient or making API calls are efficient.
If the size is more then you can go for an API call, by making an API call it will also make the option for multiselect more dynamic and benefits are you don't have to change the values every time you add a new option,
if you have like 10-15 values then you can store it in state.
Most developers prefer a API call, you can use react-query for keeping any async data synchronizaion. always the data the client sees will be up to date

React Query useInfiniteQuery invalidate individual items

How can I invalidate a single item when working with useInfiniteQuery?
Here is an example that demonstrates what I am trying to accomplish.
Let`s say I have a list of members and each member has a follow button. When I press on to follow button, there is a separate call to the server to mark that the given user is following another user. After this, I have to invalidate the entire infinite query to reflect the state of following for a single member. That means I might have a lot of users loaded in infinite query and I need to re-fetch all the items that were already loaded just to reflect the change for one item.
I know I can change the value in queryClient.setQueryData when follow fetch returns success but without following this with invalidation and fetch of a member, I am basically going out of sync with the server and relying on local data.
Any possible ways to address this issue?
Here is a reference UI photo just in case if it will be helpful.
I think it is not currently possible because react-query has no normalized caching and no underlying schema. So one entry in a list (doesn't matter if it's infinite or not) does not correspond to a detail query in any way.
If you prefix the query-keys with the same string, you can utilize the partial query key matching to invalidate in one go:
['users', 'all']
['users', 1]
['users', 2]
queryClient.invalidateQueries(['users]) will invalidate all three queries.
But yes, it will refetch the whole list, and if you don't want to manually set with setQueryData, I don't see any other way currently.
If you return the whole detail data for one user from your mutation, I don't see why setting it with setQueryData would get you out-of-sync with the backend though. We are doing this a lot :)

Replacing Redux with Apollo for local state management

I'm pretty new to GraphQL and Apollo but I've been using Redux along with React for the last 3 years. Based on Apollo documentation, they encourage developers to use it as the single source of truth:
We want to be able to access boolean flags and device API results from
multiple components in our app, but don't want to maintain a separate
Redux or MobX store. Ideally, we would like the Apollo cache to be the
single source of truth for all data in our client application
I'm trying to figure out the way to replicate with Apollo what Redux would allow me. In my application, I have "Tags", an array of objects with close to 15 different fields each. They are used on 3 different sections of my app and each section shows specific "Tags" as well as specific fields from the "Tags". Based on that, the way I approach this with Redux is to fetch the "Tags" from my API, and, in the reducer, I create different arrays containing the IDs of the specific "Tags" I need for each section and I also create a Map (id, value) with the original data. It would be something like:
const tags = new Map(); //(tagId, tag) containing all the tags
const sectionATags = []; // array of ids for section A tags
const sectionBTags = []; // array of ids for section B tags
const sectionCTags = []; // array of ids for section C tags
My goal is to replicate the same behavior but, even though they encourage you to manage your local state using Apollo, I'm not sure if what I want to achieve is possible in a simple way, or if it is actually a good practice to do so with Apollo. I've been following this example from the docs and what they mainly do is adding or removing extra fields to the data received from the server by extending the query or mutating the cached data with the #client directive.
At the same time, I understand GraphQL was meant to query the specific data you need, instead of the typical REST request where you would get a big JSON with all the data regardless of whether you need it or not, but it feels like it wouldn't be efficient to do 3 different queries in this case with the specific data I need for each section.
I'm not sure if I'm missing something or maybe Apollo is thought for "simpler local state management". Am I following the right path or shall I keep using Redux with another GraphQL library that just allows me to fetch data without a management layer?
Apollo has normalized cache ... you can query once all [fields required anywhere] data - subsequent/additional queries can be "cache only". No additional requests will be made - it's safe if all required fields already exists.
Converting data structure ...usually not needed, we're working on data [and shape] we need ("not our but backend problem"). You can:
change data shape in resolver [in graphql API wrapping REST],
reshape data in REST-link (direct REST API access from Apollo),
read data once at startup, save converted in local (all following queries reads local)
Common app state can be left in redux - data fetching should be in apollo.

How to store and exchange big firestore data between seperate components in angular?

I have a long length array of numbers in firestore. This array is also just one of the property of my object model.
3 of my components on different pages need this array;
1st component doesn't need this array but needs another properties of my object model. So i have to fetch it from firestore without any other reason.
-2nd component needs this array to reduce its values and display result on the page.
-3rd component needs to display whole array data.
What is the optimized way to store and exchange these data between those components to avoid any memory leaks or unnecesary firestore calls (free calls are very limited and it makes my web app much more slower)??
I tried to assign this object to my service but hence it is an observable i had to subscribe to it everytime a component needs this data.
Need your help.
Thanks in advance.
I would stay with using the obervables, so you can make sure that the state within your forms stays in sync with your array data. If you start moving copies of your array around you would have to establish additional state management like Ngrx etc. to achieve this. Also Firestore has a caching feature built in, so it's not always reading data from the server.
Cheers,
Lars

Resources