React Query: When to use useInfiniteQuery or usePaginatedQuery for pagination - reactjs

I have a table like this
which renders paginated items. The exact number of the times is unknown at the time of the API being called. So for handling pagination of a table like this. it is better to use useInfiniteQuery or usePaginatedQuery from React Query?
I am really struggling to understand the differences of the use cases for these two APIs here

As far as I understand by reading a bit of the docs, usePaginatedQuery will return resolvedData that just equals the last successeful page's data, it won't concatenade the last page's data to the data you already had. On the other hand, useInfiniteQuery does this with fetchMore.

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 :)

Efficient Firebase document reading and querying with hooks

I am currently using queries to get the initial state of a user. They potentially could have thousands of individual documents that don't need to be set up via hooks.
My current approach is mostly working, however it does mean there is a double read on the documents that I create the hook on.
query(
collection(firestore, "userDocs"),
where("ownedBy", "==", userId),
orderBy(documentId()),
limit(6)
)
This is my initial query, I am using react infinite scrolling to then fetch more as they scroll down. Each of these documents is a rendered component in React.
Within that component I then setup a hook to pretty much go and get the same data that I just did.
setCol(doc(firestore, "userDocs", userDocId),{
snapshotListenOptions: { includeMetadataChanges: true },
})
They both set a document state on the component, once on load, and when ever the firebase hook goes off. I am using a react firebase package here for hook simplification.
My question is, how can I get this hook functionality which I really need, but stop this initial read from the firebase hook. If I don't do the initial query for the documents, I don't get the data I need to make the hooks. And also an approach I tried of just using hooks passed to the user doc component was much slower than my query based approach because firebase queries are really fast than singular document reads.
I am basically trying to prevent a second read when the hook on the document is created because its data will just be the data I got back from the query and isn't very efficient. I have seen some implementations that get around this using a timestamp updated at field, but does that require me to perform an extra write on the documents that I've just queried?
When I update the document that triggers the hook its possible I can pop a timestamp field in then but Im not sure how that solves my initial read problem.
Many thanks for any suggestions :)

Should I filter an array by passing a query string (the search param) or state with history.push in react is?

I am filtering and updating rendered cards from an array of cards on a product index page. Now my question is, what the benefits va downsides are for using state vs search as a param with the useHistory hook from react-router-Dom v5? On most e-commerce platforms it seems to be the case that the query string param for filters is always set, I.e …/buy/?category=seating&option=chairs, and then a state is populated whenever the search param changes.
However, isn’t it much easier and leaner to just pass state with useHistory instead? Then one wouldn’t have to worry about all the history.replace() calls to update the query Params whenever a filter is updated or selected.
Would love to hear some advice, also if I should be using query strings (the search param) at all, and what the benefit is opposed to just sending an updated state.
Essentially, with all the query string population, the code gets quite chunky(keep on calling history.replace and history.push for each filter. And I have filters for minprice, maxprice, category, brands, options, as well as sorting
I would say that both ways are valid ways of sorting things, though with params you get the refresh feature without using local storage, I personally just use the state way and filter, you can probably do the params way and just have a Context around the products pages, and share the list between all the pages, then filter based on the params/state. Regarding the history.push, should honestly be fine, though I recommend using the newer version of react-router.

How to paginate unpaginated data with SWR

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.

React / Redux - How to handle multiple async calls when loading component

I'm pretty new to React / Redux, but love to play with it so far.
I came accros something that actually bothers me, but I'm not even sure it's a "real" issue I should care about. Anyway, here it is.
Let's say I have a component, which is actually a form for updating a record, retrieved from a database. This record has several foreign key to different tables. (Let's say my main table is Training, which has a Format, a Type, a Place... and all those data come from another tables).
In order to be able to display all the possible values for each of the foreign key to the user, I have to request all the different tables to get the data, and display those in dropdowns.
For now, I'm doing something like :
dispatch(new CrudActions(places).getAll());
dispatch(new CrudActions(trainingFormats).getAll());
dispatch(new CrudActions(trainingTypes).getAll());
Each of these line will dispatch a redux action, and so, update a part of the state, according to the data that is retrieved.
Then my component will then simply get the values from state :
function mapStateToProps(state) {
return {
places: state.places.list,
trainingFormats: state.trainingFormats.list,
trainingTypes: state.trainingTypes.list
}
}
It's actually working, but the consequence is : each time an action finishes and updates the state, my component get re-rendered... Let's imagine my main training has 10 foreign keys : for a single page load to display the update form, my component will be rendered 10 times.
Wouldn't it cause bad performances ? Is there any better way to retrieve foreign data ?
Let me rephrase that. Each of your record components has dropdowns for places, training format and training type. The dropdown options are retrieved via ajax. When you have several records, there will be a lot of requests and rerenderings.
The solution: Don't let every record component retrieve the dropdown values on its own. For each respective dropdown, they are all the same anyway. Instead load them in one of the parent components and pass them to the record components as properties, for example as availablePlaces, availableFormats, availableTypes.
Your parent component does not even have to load the available dropdown options via ajax. It can be initialized with it.
For further optimizations concerning rerendering have a look at https://facebook.github.io/react/docs/react-component.html#shouldcomponentupdate.
Facebook recommends making ajax calls in https://facebook.github.io/react/docs/react-component.html#componentdidupdate.

Resources