How to Use React Query with NextJS 13

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
managing asynchronous State and react application can sometimes be more problematic than expected tan stack query formerly known as react query is a great library that helps make this process much much easier this video is intended to give you an overview of how to set up and use tan stack query in an xjs13 application this isn't meant to be a full code Along video but I'll walk through the process of setting up a majority of the functionality of this application so hopefully after watching you have a great starting point to implement tan stack in your own applications we'll be going over how to set up both of these components to fetch all of our data to add a new to do we'll show the process of creating a spinner and disabling an input when something is loading our toes pop up our new to do has been fetched we update the status with disabling the buttons we see the crossout with another toast notification and we can delete a task as well so let's go to the tan stack website tanstack.com you can see here we've got a number of different things that they provide for us what we're going to be working with is tan stack query so let's go ahead and click on that um you know we're greeted with another page here with a bunch of stuff but let's click the get started button the documentation here is definitely worth reading it gives you a lot of good information on the how and the why of tan stack query we're going to do kind of a simplified demo today running through and building out a to do application I made another video that I'll link up top that just goes over that same to do application and just explains why we want to use tan stack query and what kind of problems it helps us solve if you're interested in watching through that before watching this video go ahead we'll link it at the top but you can see on the tan stack site they kind of give us an example of this which might up top seem confusing because it's all kind of just in one big code block right but we'll walk through the process of setting this up specifically in next js13 so if we go to through installation you can see we've got npmi tan stack slash react query so in your code editor npmi tan stack slash react query I'm not going to run that because I already do have a dependency installed if you're using pnpm or yarn you've got those options as well and then one other thing that we're going to be adding here is they do have Dev tools so we do want to take a look at devtools and get the same thing npmi and tan stack slash react query Dev tools uh blow that up and again I've got that already pre-installed so we're not going to do that but devtool is going to be really useful to help us see what's happening when it comes to query functions which we'll get into in a little bit so I'm working in a next js13 application here and the first thing we're going to want to do after we install tan stack is we're going to want to set up our providers so tan stack does utilize context to provide data throughout the entire application so we're going to go ahead and set that up so I've got a providers folder under my components let's add a new file we're going to call this tan stack provider.tsx now if we go back through the documentation here in the quick start guide you can see they give us a little bit of uh set up here right I'm actually going to differ a little bit from what this indicates and I'll speak to that in just a minute so here since we are using context we're going to have to declare this as a use client as a client component so we're going to import a couple things we're going to import our query client provider from tan stack react query and query client will also import from requery Dev tools we're going to import react query devtools and the only other thing we're going to import here is you state so we're going to set up our component uh our provider component here const we'll call it tan stack provider equals and it's going to be a function right and we'll have our return with whatever that's going to be and we'll export default hand stack provider and then return we're going to return our query client provider and within that we're going to put children right so react children if you're not familiar with how this works whenever you have a component in react and you've got your opening and closing brackets if you put something between those opening and closing brackets those are children so we're going to import that prop uh which we're going to call children and children is going to be typed I'm using typescript here react dot react node if you're not using typescript don't worry about this if you're just in JavaScript so query client provider does take a prop which is called client and we haven't set that up yet and this is where I'm going to differ from the documentation a little bit so if we look back at our documentation we see we uh they they indicate const query client equals new query client and brackets right that's one of the things we've imported and that is what they're sending in as that client prompt I'm going to differ a little bit we're going to actually put this into State when I've done this process I've seen a lot of disconnects in how react query is tracking the query functions which is really a big deal query functions help us manage state that we're pulling down with react query and refreshing that state so like if it loses connection it's not going to work correctly so you can try this method that's the reason why we're installing the dev tools if you see disconnects or disappearing state which I'll point out again later then you might want to try this method that I'm going to go over so what we're going to do is we're going to say const query client equals use state and that's going to take in function new query client all right and now here we can put our query client to save that we get a little bit of a difference in formatting and one thing I'm forgetting here is we do so I'll change this formatting again because we do want to put in our reactive tools so here we can put react query Dev tools and we can close that out there are some props so we're going to put one prop uh initial is open we're going to put that as false so basically what that's going to do for us is we'll see a little symbol on the bottom of our screen that we can click on to open up a Dev tools view it's not going to just be open automatically now we'll save now we'll have a nice little better formatting and there we go that is our provider setup and ready to go so now we need to actually put this provider so it can give all that data to our entire application so in next.js13 we have this layout file layout file is basically where everything lives right so this one looks a little bit messy right now because I do have a bunch of other stuff here going already I've got a toaster component from Shad cnui uh I've got a theme provider going on here and I've got some session provider stuff from auth JS so we're not going to go through the process of sending all that other stuff up in this particular video this is really just centered on tan stack and working with tan stack if you're interested in some of that other stuff let me know and I can put that together as well so now that we're here we're going to import our tan stack provider that we just created from our providers component and then from that point we'll just wrap it around our children right that's already going to be here in your layout file when you make next 13 project provider let's get our closing tag and put it in the right position at the bottom okay so as long as we have this wrapping around our children children is going to be any pages that you render throughout navigation so we're basically anything within your app and any components within those pages so now that that's there we're going to have access to tan stack and our caching layer now you can see here this is our main page that we're going to be loading upon application load we don't really have anything going on here right now you can see we're calling get off session which is a custom function that I'm just outputting from next off basically just in This Server component because we don't have the use client directive at the top so this is a react server component this is just checking our user session to see if a session exists if not we're just going to return a sign in to see tasks and if it does exist we'll return some other stuff that we're going to work on together let's go ahead and let's start with one thing we'll start with the to Do's section our to-do's component is what's going to actually call out and fetch that data for us so in components let's add a new file and we will call this to dos.tsx we're going to make this a client component right anything with tan stack is going to be client-side you're not going to use this in any server components so first we'll just do we'll set up our basic thing const to Do's is a function export default to do's and what are we going to do here well basically in this function in this component we want to have the component fetch data for it to do's and then we want to render those to-do's right we want to do a couple other things too we want to indicate to the user if this process is loading we want to render that and if we hit an error we'll render some kind of message right so the first thing let's do is let's just build out a div here because we know this thing's going to live in some kind of container I'm going to add some Tailwind styling here and then we're going to end up mapping through to do data here we're going to run through the process of setting up our first react query data fetch so one thing that I'm just going to import right now um which you'll hopefully know the shape of your data I'm going to just import this interface called to do when we call out to the back end this is the information we're going to get back for each of the to-do's we receive so I just want to have that there so we'll import use Query from tan stack query I also want to import axios because I'm going to use axios to do this you can use fetch fetch isn't going to throw an error axios will throw an error if it receives a status that isn't 200 so if you're using fetch you have to throw your own error I'll talk about that more in a little bit and eventually we're going to make a to do card just to display this data on the screen but we'll worry about that in a little bit so let's make our actual query to our back end so let's go look real quick what's happening in the back end just so we understand nothing too crazy again this is just kind of a basic example app we're checking a user session if we don't have a session we're going to throw a 401 status if we do have a session we're just going to query our database we're using Prisma here we're just going to find whatever to Do's are associated with the user ID that we have stored in the session and then we're going to send those to-do's back nothing too crazy we'll take a look at what those are what those look like uh in just a minute we are going to say const and we're going to put some brackets there for now and we're going to do use Query which is a function or a hook and we pass in an object now within this object we've got a number of things that we're going to pass in the first thing I want to do is pass in what's called a query key and you can see I've got some pop-ups here now a query key is what's going to help us establish this caching layer it's what's going to help us say from other components in our application hey to Do's component our data because we even have taken an action that mutated data on our database our data that we already have on the front end is no longer valid process this thing again do a refetch for us go get that data and let's update everything we've got going on so query key if you read through the documentation it's an array which you can put some kind of string which we're going to just do user to Do's here but you can also throw some extra information here like you can throw objects in here and if you needed like some specifics like user ID is a specific ID maybe you want to have something else in there as a requirement whatever that information might be these don't matter in the order that you put them in so you can put these objects in any order but we're just going to keep the simple and just stick with user to Do's right now so since this is an object we're going to throw a comma after this and now we're going to put in our query function so this takes in a function which we're going to make this an async function right because we know we're going to use axios to call out to our backer to get some data and we're going to do a couple things here first things first is we're going to const destructured data from axios we'll do a weight axios.get and then we'll throw in our API slash to Do's slash fetch which just is our API endpoint that's going to run the process as we just looked at let's console.log what that data looks like so we can take a look at this stuff first what we'll do is we'll go back to our main page here and we will import to Do's we'll go ahead and just open that up and we'll save that and let's npm run Dev so we can start our server we can look at what we actually get back before we do anything else with it okay so you can see right now we don't have a session so it does say sign in to see tasks so that part's working out correctly for us now that we've signed in we have our my to-do's output here and which is right now it just says map through to do data right because we just kind of threw that incorrect comment in there but that's okay since our component should be loading here here's our map through to do data right we should have something in the console here on our client component we can see we get an object oops let's go back and here's our to-do's right and here's an array of to-do's I've already got one thing in there so we can see that this just matches up with that interface we've got an ID we've got completed we've got created out all this stuff right so we get an array of to Do's in this object so rather than just what we would be doing here is we're going to we need to return something from this function otherwise nothing's going to go anywhere so we're going to return data dot to Do's which we saw was that array and we're going to just say this is as to do array just so we can use typescript and get some of that information back from the data that we're storing here before we make take another step I do want to note again as I indicated earlier if you're not using axios if you're using fetch I believe fetch has that like dot OK part of it right where you say like if if something is not okay which means you get an error back technically then in that case you would throw new error however you want to handle that error and that's going to allow us to understand that there was an error in the fetch process just to note in case you're using fetch or some other library to make your call that doesn't automatically throw an error like that okay so now we're going to destructure some stuff from use Query we're going to destructure data which is in this case whatever we're returning from this call we're going to destructure is loading and you can see I'm getting some suggestions here I can hit control space and I get a bunch of pop-ups here for all the things that we can destructure from here the only other one I want to use today is is error so data which we will put down here for now and we'll do this we're going to do Json dot stringify data and all two just so we can see the data on the screen for a moment and the other things that we're going to do is we're going to do some conditional returns we talked about this we have if loading render alert loading message all right so we've got is loading so we'll say if is loading because this is going to be a Boolean value for us then we're just going to return a div we don't even we're not going to style this we'll just say loading tasks and if is error we should handle errors a little bit better than this but we're just going to say there was an error try again okay all right we're saving this we can see we get loading tasks right away as we're loading and there you go there's our ugly little task uh displaying for us with our json.stringify so cool we are well on our way and we know we already got our fetch happening no use effect no anything like that all thanks to use Query so now let's pretty this up a little bit let's make some to do cards just so we can display this data in a nicer format so let's go back to our components make a new file and we're going to say to do car.tsx set up our functional component just like we did before do card function all right and our return is something card right so let's make these basic for right now to save ourselves a little bit of time I'm gonna just throw some imports in here that I already have these are going to end up being client components so let's do the use client directive at the top and we're going to import a bunch of stuff that I have here from a UI Library called chat CN we can see I've got a UI folder that has a whole bunch of stuff in it we're also going to import but from Chad CN so let's make this card component we're going to build out a card and we have a card header and in that header we have a card title in our card title we're going to put in a title we'll take care of prompts in a little bit and I want to add some styling because we do see here that we have a completed attribute on this and right now that that specific to do is false right so we're going to do some Tailwind styling here and just say if we have completed is true then we're going to do a line through otherwise don't do anything that's our ternary operator there and again I've got these squiggly red lines because I'm not importing any of these prompts yet and then I'm not doing any kind of card body even though I've got some of the stuff up here we're just going to do a card footer and for now we'll put these two buttons we're going to render in a div put some basic styling and do Flex justify between and Min with full these buttons are going to be um we'll change these in a little bit which is going to be update status and this is going to be delete so I want to take care of these props because this is kind of bothering me so what are our props going to be here well we have our interface already from this to do I've already got an export on here export interface to do so let's go back into our card here and we'll do import type to do from our to-do's component we're going to destructure from our type to do and if I hit control space now I can see all the stuff that typescript is giving me here so we're going to use completed we know we want that we're going to use the title and at some point we're also going to end up using ID in the future here so let's take that in it right now as well and now my completed and my title don't have a squiggly line on there anymore and we can see what those things are that's a Boolean this is a string and we're set let's go ahead save everything we've got so far let's go back to our to-do's where we are fetching and we'll import to do card that we just made and now instead of this json.stringify now where this is where we're actually going to map through our data right so let's get rid of all this stuff so let's map through our data so we have data which we have destructured from our use Query function dot map and we know that this is going to take let's let's call this a to do right and then for each to do we're going to render out our to do card and we know that we take in prompts now we could do this completed equals completed whatever but I'm just going to destructure to do oops this might yell at me let's see no okay so even though I'm not actually using all of the attributes from the to do object that we have that we're putting in here we're just spreading everything that we get into do so all of these things this is the equivalent of saying like completed equals to do dot completed and all of the other things that are contained within this so instead we're just spreading that out to make that nice and clean let's save that if I didn't mess anything up this should adjust now into our to do card there we go so now we see our little card set up first pass for today we've got an update status button we've got a delete button and these aren't doing anything quite yet we'll fix those up in a little bit let's move on let's give ourselves the ability to add a new to do so in components new file and we'll say make to do dot TSX same thing we've done with everything else here set this up and we know we're going to have some kind of return in here right so we know up front this is going to be a client component so index.js13 we do need to put use client at the top and in return we want to have an input and we want to have a button to submit so we're going to do a couple things here we're going to import I've got input from my Chad CN components I've got import button like we did from the other one from my Chad CN components let's also import now axios because we know we're going to use axios because if we're going to make a new to do to send to our back end we're going to use axios to do that and let's do a couple other things we're going to import use toast from Shad CN as well we need use State we're going to need State for the input itself I can tell you we're going to need some extra Imports here from wear act query but we'll hold off on doing that just for the moment just so we can make our actual component here right so let's wrap this thing in a div because we know we're going to have an input here and which is self-closing I don't need that and we know we're going to have a button that's going to say submit or something like that right on our div let's add some styling we're going to do Flex cap2 in with full just so it just takes up the whole width of this container that we have going on on this thing and I want to put a couple things in the input here we're going to have a placeholder here what to say to do we're going to put the value we know we need that here we'll fill that out in just a second we know we're going to need something on change here so we'll fill that out in a second as well we'll stop there for the moment so let's set up the state for this input button so we'll do const we'll just say input and set input equals use State and we'll just set that as an empty string for now so this will be the input and this will do on change as a function or set input is e dot Target dot value and I'll throw the e in here oops we have that event so let's just go ahead and put this back into our page let's import make to do's from make to do and fill that in there just to see that we've actually got it and there we go here's our to do input with a submit button great so let's go back and let's actually make this do some stuff that we want to do so we're going to import two things now we're going to import use mutation from react query and we're going to import use Query client the one thing I want to set up first is our query client and we're going to talk a little bit more about this in a second const query client equals use query client that's our function so this is a function that we've imported this is what we're going to call so now we can call different methods on query client so what's going to happen here well we're going to type into this input we're going to type some kind of task whatever our task is and then when we hit submit we just want to send that data to our back end if we go look at this create route that we have going on here nothing too crazy we check for a session then we take our body we store it into a body variable I'm using Zod to parse the stuff we're sending in here which is just good practice and you validate your data that way we're going to pull the to do which is to string from that and then we find the user session find the user buy session and if we can't find the user in our database we return an error on that should be there because when we do sign up we automatically create that user but okay and then we make it to do do to do create we send in the title and the user ID is the session that we found so so now that we're back in make to do is we know we just basically want to send over whatever the value of this input is right so we're going to do the same thing we did last time we're going to do const and we know we're going to de-structure some stuff from use mutation which is a function or a hook use hook it takes in an object with a bunch of different things the first thing we're going to put here is our mutation function now just like the other query function that we did this is going to be an async function and here the only thing we need to do is await axio stop post we'll use our API slash to do slash create endpoint and we'll send in an object which is our data and it expects it to be called to do and we know that's going to be our input value that's it that's our mutation function that's our post call that's all we need to do for that this is an object so we'll put a comma at the end here before our next thing so now if I hit control space here again you see a bunch of the things we have access to on success is one that we care about and on error so we're going to do on success which again is a function and we're going to do a couple different things here the first thing I want to do which I actually didn't do yet is since we're using a toast notification system from Chad CN I need to do this toast equals use toast that's the function that we've imported here and then within this on success function the first thing I want to do is throw a toast notification assuming we have success just that says this takes a object description to do added successfully an exclamation point at the end of that the next thing we want to do is we want to take this to do input and we want to blank that out so we'll do set input back to an empty string and now what we're going to do since we've got this query client we're going to do a query client Dot and you can see we get a bunch of stuff in here as well right the thing that we are going to be caring about is invalidate queries so this is the function and we can just throw our array right in here and we call this user to Do's right that was the same thing we had in the to Do's component we put this query key in as user to Do's so what is this doing for us as soon as we get a success back from axios a 200 status this function is going to run it's going to pop up with our toast notification it says to do edit successfully it's going to set our input back to an empty string and then we call query client.invalidate queries with the user to Do's array telling tan stack hey that data that we have stored in that user to Do's layer is no longer valid so wherever we're calling that which is in our to-do's component run this query function again and pull down the new data we'll test that in a second to make sure that works the other thing we're going to do here is on error and again that's a function and if we hit an error I just want to do toast with a description of for now we're just going to do something went wrong please try again I can also put in this object a variant and we can call this destructive so it's a different color it's a nice red color for us that's great so we've got some stuff here set up and ready to go for us but we didn't actually destructure anything from this use mutation function so what we're going to pull from that is what's called mutate you can just leave this as mutate that's going to be the actual mutation function that we've requested to run here I'm going to call this something different I like calling them something a little more substantial we'll call that submit you can call it submit to do if you really want to and then we're going to also destructure is loading so again if I do control space you can see I get a bunch of stuff here the most simplistic case here that we can do is just our function and is loading so we already know our input has our value and our on change and our button is going to do some stuff here our button we have our on click because we know we're going to submit this thing it's a function and we're going to call what do we call it submit to do right that's that the other things we're going to do here is in this button component I have actually modified the Shad CN button to accept and is loading prop so I'm going to pass that in here just to make this nice and pretty so when we have and is loading if it's loading a spinner shows up on the button so I've got is loading so I'm going to pass in or is loading variable and I'm also going to pass that into disabled as well just so we disable that button while this process is loading and under input we can also disable that input while this process is loading let's save everything that we have here hopefully I did this all correctly in one shot let's say this our new task is here and let's click the submit button we see our little loading spinner we see we've disabled this so we know the is loading Boolean is working for us there's our toast notification to do added successfully and now here's our new task so we know that our to do component has refetched that data for us and updated our data right we didn't use use state which we would have needed to do in a use effect so that would re-render correctly everything's just working and this is so clean and we don't have to elevate State we don't have to do any kind of hacky Solutions with use effect it just works so well okay that's great I love what I'm seeing so far let's talk about this little thing we haven't really touched upon yet which is our react query Dev tools so if we open this up you can see we've got user to Do's here that's that query key that we have listed previously in our query function and you can see this is a stale react query I'm not going to go through this on this specific example but you can set the amount of time that something is considered valid for or fresh for your data with react query basically as soon as it pulls this by default as soon as it pulls down that data it's going to consider it stale in most cases that's probably okay but you might have something where you just want that data to stay longer for valid for a longer period of time regardless of what else is going on another fun feature about react query is if your user navigates away from the page so all I did was click on our code over here and then we click back did you see that how that switched to fetching so if your user is switching tabs there is a possibility that whatever data you were pulling down from your database when they come back to that tab is no longer valid react query handles it for us automatically just navigating away from a tab and navigating back and refetching that data what a wonderful thing to not have to worry about you can test these things yourself you can click refetch you can click and validate and all this other stuff but this is just and here is kind of your data that exists in your your caching layer if you have multiple query functions going on with different query Keys you'll see them listed out here again like I stated up top when we were setting up the provider if you see this like flash out at some point and disappear maybe you're using that const method instead of the use State method in your provider try one or the other and see which one works best for you I recommend that you state especially if you're using next 13 that's what I'm familiar with and that's where I've seen this most effective all right we're done with that for now let's move on hello Eric from the future here while editing I realize there's something else I really should have covered for you all when you're handling errors from your calls like I did note before axios is going to throw an error automatically on an error status if you're using another Library you might need to use the throw new error process there you can actually pass in your error here we're just going to type this as any for right now typically if you're looking at your error you might have like error.response.status is typically what you're going to see so you can actually give more meaningful notifications to your end users if you do something like if error.responsive status is equal to oops is equal to 401 then you can do a toast notification for you know like user not found or whatever you're trying to indicate based on whatever your responses are from your back end so just a quick extra note there on that that you do have access to the error object we're going to make this use status and delete button work as well and honestly it's the same exact thing that we just did over here with this use mutation we're just going to do it again in the card component so we'll navigate back to to do card honestly if you wanted to you could make these buttons their own components I'm going to refrain from doing that just because I don't think it's necessary in this specific use case but if you wanted an update status button or something similar in various parts of your application that did the same kind of process and still needed to rerun that same query again you can make it its own component and just plug it in wherever it needs to be so now that we're back at the new card a couple other things we're going to want to import here we'll do them right at the top we're going to import use toast again just like we had in the other component and we're going to import axios because we know we're gonna need that again use mutation once again and use Query client just like we did last time so we've got the stuff here we need we're going to move down a little bit we're going to set up our toast with use toast again from a Shad CN if you're not familiar with our library I'll try to make sure I put a link below in the description it's a phenomenal Library please go use it makes this stuff a lot nicer and you could develop a lot more quickly and we'll do const query client equals use Query client there we go we've got these buttons that don't do anything yet but let's go ahead and set up what those functions are going to be so let's do the delete one first I guess why not on our back end we won't look at it all we're going to do is send it a ID number which is what we we have an ID number for each of these tasks so we're going to do const equals use mutation function object in there same thing we did last time mutation function it's an async function and in this case we're going to do a weight axios dot post link to our API endpoint to do slash delete in this case and we're going to send it some data it expects an ID we're going to send it the ID comma because we're in an object here then we have our on success call again it expects a function so on success we'll do what we did last time we're going to put a post a toast notification pop up with a description that just says task deleted because we're deleting the task in this particular case and then we're going to do exactly we did last time our query client Dot invalidate queries which is a function takes in our user to Do's string inside that array and then we have our on error which is a function another toast with a description there was an error please try again and we'll throw in as well as that string a variant which will be destructive so we've got the setup let's see structure so again this is mutate which we're going to call delete task and then we also have is loading now I'm going to name this right now because since we're going to have two of these in here we'll have two different is loadings and let's just call this delete loading and that's it for right now so let's go down to our delete button we'll adjust our on click Handler here to a function and this is going to be our delete task function we call and we have some other stuff here where we can do is loading we looked at this before and we're going to do delete loading and then disabled for now we're just going to put delete loading here as well and let's save this and let's make sure that this works for us so here we have our new task I'm going to click the delete button we see our spinner there was an error please try again let's hit that one more time I think something may have just been going on with next.js loading we hit delete there we go task deleted but we did see an error message so we know that that error message works for us as well right something went wrong on our back end there was a miscommunication in the server whatever we saw that error message pop up correctly I was gonna was gonna just go through and change my back end and force an error out for us but lucky enough we just saw that process so great task deleted we're good to go we know deleting Works let's do this update status to save ourselves some time I'm going to copy everything here that we just did and we're going to make some changes here instead of this called delete task we'll call this update task and then we'll call this update loading and instead of going to a delete backend we're actually going to go to a status back end and here we're going to send in the ID but we're also going to send in completed whatever the current state of that task is and then here we'll say task updated play task status updated same thing queryclient dot invalidate queries refetch that data for us and on error something went wrong right so we'll make the same changes to this update status button so on click Handler function this one is now our update task function is loading is our update loading Boolean that we destructured and for disabled now let's make an update here let's do update loading or delete loading right that way regardless of what button you're clicking and we'll update this one as well both of those buttons will just become disabled so you can't click update and delete and have both trying to be called at the same time I think if I didn't miss anything through that copy and updates process I believe now we can clear that I believe if I click update status we see both of them now go disabled we have our spinner here because that's the one that's actually loading task status updated and now we see our strikethrough from our ternary operator here for our Tailwind styling on our title there we go um hopefully this has been a good overview of how to set up tan stack query in an xjs13 application how to utilize the use Query functions and the mutate functions the use Query Hooks and then use mutation hook and hopefully this helps you write cleaner more concise components in your react applications and makes hopefully the process of managing asynchronous State a much more enjoyable developer experience if I missed anything or if you have any corrections for me please feel free to comment below if you appreciate this video and think it's helpful please go ahead and share it with folks that you know and help spread the word here thank you very much for tuning in
Info
Channel: EricWinkDev
Views: 17,700
Rating: undefined out of 5
Keywords: react, query, react query, tanstack, tanstackquery, reactquery, nextjs, nextjs13, app router, app, fullstack
Id: G0BmM-L5FoE
Channel Id: undefined
Length: 40min 54sec (2454 seconds)
Published: Sun Sep 10 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.