Why I don't use React-Query and tRPC anymore

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
everyone I've been getting some questions about using react query and trpc in the latest nextjs so I personally do not use react query or trpc anymore and in this video I want to explain why I don't have anything against these tools in principle I think they're still very useful outside nextjs and I also think that the people who build them and maintain them are very talented people let's actually take a look at why I don't use them anymore so I'm going to use this remote Dev project that is from my reacted next escore some of you will recognize it and here we are actually doing some data fetch so let's actually start with react query so the user can search for something and then we get a list of results and the user can click on one of those results to get the detail right so here I clicked on the at security so that's what we see here let me actually zoom in a little bit so you can see here that I can click around and every time I click on one of them we are loading the actual details of that particular job item right very standard very typical situation here I'm using the same image for all of them by the way so don't be confused they are actually different right so you can see the title here is front end devel veler react and the company name at security here the company name is Asen as so you can see we're we're loading the relevant details for the one that we clicked and when I look in the network tab you can also see that whenever I click on one of them there is a new network request so the data is being Fetch and most importantly when I click on one that we already saw there is a new network request all right so how would we implement this well traditionally without react query you would have the typical use effect right so you would use use effect and then you can use the fetch API to actually fetch the relevant uh job item details right based on the ID that we get here we're going to set the loading is to set to true and ultimately we get the data so we store that in state and then here with is loading we're setting that back to false again right this is basically how you learn react initially right so you have use effect and that's how you fetch data the downside of this is now if I click on the first one you can see there is a network request if I click on the second one there is a new network request what happens if I now go back to the first one the one that we just fetched if I click on the first first one there is a new network request there is no caching and when I go back to the second one there is a new network request we see a loading State there is zero caching so literally every time we click on one of them there is a new network request and that is very inefficient right because why are we making a new network request we just requested this information 5 seconds ago so that's where react query comes into play so let's actually replace this with react query all right so I have commented this out and I replaced all of that with react query here so with react quer you get the use Query hook and it will give you the data and an is loading flag as well so with react query um there's three arguments here that will specify so this ID is like a caching key the second part is the actual data fetching right so with react query you still have to specify how you want to do the actual data fetching and then how long it should be cached so what's the benefit of doing this well if I now save here and now uh Let me refresh here for a clean slate all right so now we see the first one here what if I click on the second one well it's going to fetch initially it has to fetch the data right but what happens now if we go back to the first one you can see that was instant right if I now click on the second one you can see that's instant there is no loading State now I can click around between these two because they have already been fetched once and react query knows that if it's an ID that it has seen before right which is why we keep track of it in here it can see that when you pass in an ID and it's an ID that we have already fetched for before react query knows uh we already did this data fetching for ID number five let's say so we're not going to run all of this again I'm just going to give you the data from that number five from before so that's called caching and let me show you that in a network tab as well so if I click on the last one here in the list you can see there is a network request here and there's no way around it initially you need to actually fetch the data and now let's say I click on the one uh on top of that so there's another Network request okay it's the first time so you're going to have to get the data but what happens now if we click on the last one again you can can see I clicked there there was no new network request if I click on the one above it you can see there is no new network request I can I can click back and forth between them there are no new network requests because react query caches these job items um when we fetch them now react query can do many other things but I would argue that this was the main reason we were using react query and this is still how I would do it in a react feat app right so remote Dev is a react feat app and in a feat app I would still use re react query all right so that's for feed right nothing really changes for react feed apps or create react app in case you're still using that right so that all states the same now in nextjs I would argue things change a little bit so here I actually converted the same app to uh the nextjs framework so here it's the same app all the same features and you can see when I click on the second one you can see there's a loading indicator there and if I click on the third one there is a loading indicator but what happens now if I click on the second one the one that we just saw that we already fetch the data off you can see it's instant when I click here it's instant right so these first three I already fetched their data so the next time I come back to them I'm there's not going to be a new network request because nextjs actually caches that for me so let me show you how it looks like in nextjs so in nextjs we do not use use effect we can actually make it async and then you can do the data fetching directly here in the component function body and then if you do it like this next as will automatically cash all of this and let me prove that to you in the network tab as well if I go to the second page here let's say I pick the first one here you can see there is an initial Network request if I click on the second one here there is there are actually two Network requests we can ignore that but you can see there is a network request for every click what happens now if I go back to that first one that I just clicked if I click on that one you can see it's instant there is no new network request if I click on the other one you can see it's also instant there is no new network request because nextjs automatically caches your fetch request actually and how do we get the loading State like we got with react query though because if you look here you can see we are still getting this spinner here so how do you get that loading State actually the loading State Works a little bit differently so on the page in a nextjs project so here on the page component here is that component that's actually doing the data fetching I can wrap it in a suspense and then you can specify a fall back so while the async component is suspended right you can see right while this is going on it will render the f back here and this is the component that actually shows a loading spinner right so you can see here there is a spinner in here right make sure you add a key prop to the suspense so that every time the ID changes the suspense is triggered again very common Pitfall actually right so next you ask comes with built-in caching so that's why I don't use react query for data fetching in nextjs right so nextjs is very aggressively cached actually so it will actually automatically cach the result of this fetch call this individual fetch call whatever result of that is it will actually cash that and that's actually the most powerful cache in nextjs this will persist even throughout deployment and nextd S also caches the result of this render right so your server components this is your server component the result of this render is a so-called RSC payload react server component payload so basically the render result the render result itself is also separately cached and there is also a client side cache that nextjs manages for us and that's actually why it's so Snappy here because as I click around it will actually use that client side cache right so it will not make new network requests to the back end because it can see that we're requesting something that has already been requested before right so those are the three main caches in nextjs now if you use the nextjs link component which we actually do use here in that in that list so for every item in that list it's wrapped in this link component where it will actually specify what needs to happen to the URL when you click on it this is actually prefetched so as these links come into the viewport nexts will automatically prefetch that for me behind the scenes so then when you click it there won't even be a loading state it will be instant now here we still get a loading State because I'm in development here so that link component prefetching is only enabled in production mode that's nextjs is very aggressively cached and that's why I don't use react query in nextjs however sometimes you still need to do client side fetching right so there are still some edge cases where you where you actually want to do client side fetching in that case the fetch API for example is not automatically cached right so this is only automatically cached on the server so if you do client side fetching you may still want to use react query and usually that's the case when you want to fetch data after a user action for example infinite scroll right so the user first has to scroll and then you want to fetch data well you may want to look into react query or you want to do things like polling and some other things in that case you may still want to use react query in nextjs but generally I don't use react query in next J all right so what about trpc let's go back to our feat example so TR RPC is for client server communication making that type safe so let's actually go back to this example of fetching data without react query just the traditional way right so we just use use effect here this is how you would do it traditionally you would fetch the data like this now one of the problems with this is when we get data back here if you hover data you can see it is typed as any and we don't want to have anyes in our codebase because any means anything goes typescript should warn me here hey this method does not exist but as you can see because it's as any well you can do anything this is not type safe so the main problem here is you don't have a good type here another problem is of course you need to remember the actual URL of the end point that you're making that request to right so this is not a robust way of communicating with a back end all right so then here I have an example of trpc so you have to do some setup there is a little bit of a boiler plate here but the benefit is now I don't have to remember the end point I can just use trpc I can see what I have available trpc oh I have a job python by ID method on here and what do we want to do with that well I just want to get data that's called a query and actually I need to pass some value to the endpoint if I forget that typescript warns me here so I get a warning here I need to specify an input right if I pass in the wrong input of a number type let's say I even get a warning it should be a string right so I'm just going to pass that ID so I'm getting a job item by its ID now the main benefit here is now when I hover data you can see I'm getting the actual type right so here now I get the actual type so now if I make a mistake on this and I think I can call some method typescript will actually warn me right and I can fix my mistake so now this return value is properly typed and another benefit is of course I don't have to remember the actual URL of the endpoint right so I can just use some trpc object here and tapescript will provide intelligence here to see what I can do with that all right so then let's go back to next JS how do we get those same benefits without using trpc so trpc is for when you control both the client side as well as the server side right so realistically you're not going to do a fetch call to some third party API most of the time typically you're going to get this type of data from your own database and you're going to use an OM right so here for example with Prisma if I get the job item by ID if I now hover the data you can see I already get this correct type and I also don't have to remember some URL right so for getting data I don't need to use trpc to get these benefits server component allow me to use Prisma directly here right so with server components in xjs and your omm you already will get the correct type here right so to get those benefits for getting data you don't need to use trpc all right so that was for getting data now what about mutations right basically your postp put and delete request well if you have some kind of form let's say and when you submit the form you want to add let's say a job item to the database right so what you would do typically before trpc again you had to sort of guess the URL for the endpoint and here you need to pass the actual data but how do you know the specific data or format and here I don't get any intelligence here right I don't get any relevant intelligence here so I don't really know what to pass exactly I'm just kind of guessing here also if I get any return value let's say an error or something like that right so if I get any return value here you don't get this properly typed you're going to get some any type as we saw before all right so what if we want to do the same with trpc well you can use that trpc object so I can use intelligence here to see the options I have here so I don't have to guess the the endpoint URL I can see there is some option to create a job item and I want to do a mutation so I can do M mutate and then here I can pass the data how do I know what data to pass typescript tells me here so the input needs to be an object with a title and description right so here I can see what I need to pass right so description and title if I make a mistake if I make it a number I get a warning here from typescript so you can see all of this is properly typed including any return value I may get if I hover data you can see data is going to be of this particular shape right so with trpc you get that very nice types saave client server communication all right so then why not use trpc in nextjs well nextjs has another major Innovation and maybe this is even the biggest one which is server actions so server actions are meant to mutate data on the server so instead of using the onsubmit event handler you would actually use the action attribute and then here you can invoke a server action so I actually created a server called create job item I actually put that in a separate file we'll take a look at that in a second I could technically also Define it in here if I wanted to but I like to put them in a separate file I can also do uh create job item right I don't have to remember a URL if I don't pass anything typescript will warn me actually right so it expects an argument here I know I need to specify an argument here and then here also you can see I'm getting intelligence here so TP is telling me hey you need to pass description and title right so here I can say title if I make a type mistake again you can see I'm passing a number here I get a warning here right so here you can see type number is incorrect I can fix my mistake right so with server actions I also get that intelligence I don't need to remember some URL endpoint and if this returns anything if we uh get something back here if I hover a result you can see this has been automatically inferred by typescript and so these server actions you can call them from anywhere from the client side server side and so these server actions you can invoke them anywhere and they provide the same benefits and so the server actions are very similar to just normal local functions right and typescript can infer whatever you return from that function it can infer what you are returning and so then here as a result we get that type so let's actually take a look at how we Implement a server action like that so I like to put them in a separate file I don't want to have them lingering around in some components they're very important functions actually so I want to have a dedicated place for them in my code base so with us server at the top of the file every function in here becomes a so-called server action so here I have my server action here I Define the input right so you need to pass a new job item and it should be an object with title and description just like how you would specify normal function with its parameters right so you would give a name for the parameter and then the type and whatever type you specify here that will automatically be uh suggested here when you try to use it right so here we got the intelligence because I have typed this here I didn't need to do anything else since surf actions are basically like post API endpoints next s behind the scenes will actually make a post request to uh the back end and since we cannot trust anything coming from the client we do want to validate that whatever we get here that this is actually of the shape that should be right so if we pass something that's not of the correct shape we are actually returning something here from this function just like you would return something from a normal local function and whatever you return here this is also what you will get here as the type right so types skit will just give you that type right so it could be this type in case there is a validation problem right and then we can do the actual mutation in our database and then with revalidate we can update the UI in the same network request I have other videos and server action so we can't spend too much time on them but you can see that we get the same results here with just using server actions there is no additional boilerplate required to make all of that type safety work server actions also have some additional benefit for example here in forms they provide Progressive enhancement which is a very fancy word but it means that if you just specify the server action like this this will actually work without any JavaScript enabled and if you actually do provide some more code like what we we're doing here and maybe here you also want to have maybe a toast message in case there is an error if you do it like that it will actually need JavaScript but then still this form will be prioritized in hydration and the server actions are also integrated with some powerful hooks like use form status to get a pending State and also use optimistic to get optimistic UI one downside here is I did type it as an object like this realistically like I just said we don't really know what we get here you cannot trust any anything coming from the client and with typescript you do want to be as precise as possible so a more precise type for this input is actually unnown we don't really know what we're going to get this would be a more precise type and then you need to validate it with for example zot which is actually very similar to how you would do it in trpc as well so that doesn't change you would run it through some schema first and then once that is successful uh you would use that variable right so then you would use validated job item. dat. tile. data and then here here you also get the proper type right so after validation you do get the right type here on the backend side now the downside of doing this is now when you use the server action since it's typed as unknown we don't really know what we need to pass here right so now we lose that intelligence so that's one downside if you properly type it you do lose the intelligence now there are some rapper libraries that will fix that so my guess is that we will get some rapper library for Server actions that that will fix some of its downsides now one major downside of server actions that is going to be hard to to fix is that you cannot easily use them outside nextjs so if you also want to support let's say a react native mobile app client you can't use these server actions so if your plan is to support clients outside nextjs you may want to stick to trpc so if you're a little bit confused by now completely normal nextjs has really changed the landscape of web development in my opinion if you want to master latest react and nextjs I highly recommend you go through my professional react and nextjs course in which we start from absolute scratch and by the end we're building some really cutting edge nextjs applications you can find the link in the description so just to sum up this video I would still use react query and trpc in a react feed app for example but in a nextjs application I'm probably not going to use react query or trpc I'm doing some client side data fetching in some Edge case in which case I would use react query or I'm planning on supporting clients outside nextjs in which case I would use trpc for my endpoints thanks for watching this video and I hope to see you the next one bye
Info
Channel: ByteGrad
Views: 53,773
Rating: undefined out of 5
Keywords: react-query, tanstack query, tRPC, next.js
Id: 51pf_nCJpwg
Channel Id: undefined
Length: 18min 58sec (1138 seconds)
Published: Mon Feb 12 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.