16:40 Jack small improvement you could make here. Instead of `typeof pokemon[0]` you can use `typeof pokemon[number]` which will get the shape from all objects in the array, not just the first one :)
That's really bad. I feel like this is a bug, because it would mean that you cannot use code that is not written with NextJS in mind. Calling fetchData() directly (as long as the its arguments is stable) in vanilla React works as intended.
Yep, same here. I was dreading having to hear the word "memoize" because if we are getting to that (and we are creating the same kind of behaviour here), it just seems convoluted at that point.
But this begs the question. What is NextJS doing to React Components that are rendered client side, compared to vanilla React? It seems odd that they would have different semantics.
They aren't doing anything different with the client side components over regular React. They are just allowing only certain components to be marked as client side so only those components need to be hydrated on the client. Which is, potentially, a big improvement in time to interactive.
@@dealloc I don't think so. I saw this exact same issue with the experimental branch of React after the RFC came out but before NextJS 13 got released.
The official document says fetch api(the special fetch api used for server components) doesn't support client components yet ! which means the infinite loop can happen like that. They recommend to use swr or react-query in client components !
I mean.. Man, there's already content for it, like this th-cam.com/video/_w0Ikk4JY7U/w-d-xo.html and this th-cam.com/video/__mSgDEOyv8/w-d-xo.html, but I guess you want to hear those changes from Jack
It's fascinating to see the patterns of old PHP emerging in React with server components. Reminds me of the 'the loop' in WordPress where you loop over 1 DB query result then for each given item fire off a load more DB requests to render a template. I wonder if this pattern could encourage a lot of n+1 issues. Do you know if it's possible to use something like dataloader within react server components?
They definitely are. Otherwise the output of the fetch is Promise so the generic is . You have to type the promise for the generic to do anything useful.
Hey Jack. Thank you for doing this and the use hook clearly has potential to be a real ugly foot gun. I'm sure most people wouldn't want to create their own promise cache like this. You also probably want to be able re-fetch, retry requests, invalidate the cache etc. All of which is built in to for ex react-query. Could you maybe do a video of how to use react-query with the use hook and server components? Or will there be other tools to support the "new" Next 13 way of doing things?
React team will create an RFC for a cache solution. They mention it in "use" RFC -> "a separate RFC will introduce an API called cache to assist with caching data. Taken together, these proposals will unlock official support for Suspense for Data Fetching." I'm guessing that solution will mostly be used by libraries that you would consume. Maybe Next.js team will do their own solution based on that cache API, who knows.
I think the RSC thing could be a nice win. That's the async component rendered server side only with zero hydration. But... the `use` thing, I'm not sold on.
We will still be able to do the equivalent of getStaticProps at the highest page level in the component tree, but this time we can also do more - like get global props, or specifically nested component fetching. There is still a fair amount to work out, if you are looking at this now, you are ahead of the curve, lets see how it works out when the dust has settled a bit and standard approaches have risen
That's really tough. I read a lot. I keep lists of things I want to investigate more into. I have a lot of connections that contact me when things happen. And there is Tech Twitter.
Love the videos. Have one question though, and I've tried searching for answers, but the ones I've come across seem pretty surface level so I'm asking here At around 12:55, you mention that it's very similar to the useSwr hook from swr, and since I'm already using that, what's the point of React's use hook for me? UseSwr already does conditional fetching (it's not pretty but it does it), and a lot of the behaviours that the new React hook bring seem to be already available with useSwr. Maybe the new hook just doesn't bring new things that I need?
The `use` hook is not specific to fetching data. Its purpose is to bring async/await (in general, not only fetch) into React. However it does not (currently) bring cache invalidation, and won't deal with mutations or optimistic updates like React Query and useSWR.
@@jherr добро пожаловать is welcome, but in like "welcome here", not "you are welcome" :) right one is "пожалуйста" which is confusing in it's own way, because it also means "please" :)
You set up generics for QueryClient, but then you cast it instead of interacting with the generic. What's the point of setting up the generic then if you're just gonna cast it?
IMHO, the RSC replacement for getServerSideProps and getStaticProps (although there is still static paths as a function) is a definite improvement over 12. I'm a lot less sold with `use` on the client.
Excuse my ignorance… I’m trying to understand in what scenario this pattern would be necessary? Why not just fetch from a server component and pass the data down as props to a client component that handles the interactivity? Or if you must do the fetching on the client side, do it in a useEffect hook that depends on the Pokémon selected in state? That way the component renders once then useEffect makes the fetch and then only does a new fetch when the Pokémon selection changes in state.
You can certainly do that, and I would recommend that, or using react-query or swr, over using use. This video was really meant to say; hey, if you are going to do this, then watch out because of the side effects.
is it wrong if the function fetchData does not return a promise, but instead the resolved "value" ? const fetchData = async () => { ... return await res.json(); };
Depends on what the JSON. If it's an array or an object then yes because it's a reference and the reference will be new each time and React uses references for comparison. Even if the contents of the array or object are the same it doesn't matter. If the result is a scalar value (string, boolean or number) then the data will be compared by value and if the values are the same then the loop will be broken.
Great video, I was going crazy about how to fetch data in client components. Also, what would you do if you want to persist the id in the url and get it from there? Would you trigger a router push from the client component, then the parent (server component) will catch that paran and re fetch and pass the data as a prop to the client component? Or client component can listen to changes in url? I’m a little confused about that. Thanks!
22:46 Isn't it not a proper factory function? As far as caching concerned it will create a new separate map each call. So it has to be a singleton one way or another. But how do you do client-side singletons with the new app structure?
@@jherr Yeah but NextJS 13 announcement didn't tell how do you get an equivalent of "global" client-side wrappers similar to the ones in the `_app` file in the old system. And the closest thing to an answer was in the Q&A stream and was along the line of "just put it in your highest possible client component, bro". Client wrappers now have to be inside client components, but because client components are completely ignored by the server context, it's not possible to set up a system where a client context wraps a server-rendered page and then hydrates itself client-side.
@@ra2enjoyer708 Yeah, the client side stuff needs to be leaf nodes... Sigh. The great thing about all this complexity is that NextJS is far and away the most popular React platform, and so, if we can all figure out some good best practices around this stuff, we will all have jobs for a long time. :)
great job . i got this warning yesterday. i try nextjs 13 but information not enough in web . i hope you will post more info about nextjs 13 Thank you.
Hi Jack, there's one thing that seems bizarre to me. In your example of calling the hello API, why is it visible in the browser network tab? It appears to be called twice, once on the server side and again in the browser. What's the purpose of this? Shouldn't it only be called once on the server, since it is equivalent to getServerSideProps?
Can you give me a time reference? I know this video isn't super old, but I've forgotten exactly what I was doing. I'm sure I knew what I was doing, or I didn't, whichever. :) I'll clarify it for you.
@@jherr 9:17 - I've followed along and found out that the request is made on the server as well as on the client side. When using getServerSideProps (old way, in pages directory), request is sent only on the server side, as expected.
I really don't understand. Do we have to use the "use client" directive to avoid the infinite loop request? So, what do you need to do in the server component?
In the example in the video, if Pokemon data changes in the BE and I already have it in cache, the only way to revalidate is to delete Pokemon key from the map when I want latest data ?
Hi Jack, thank you for the great content, but what happened with the TypeScript Design Patterns series? You mentioned you were going to cover all the GoF patterns?
When have Pokemon become the goto for devs for little API-test-sites?? Is this necessary? Aren't there a million other possibilities... ? I see this everywhere and it is quite annoying to say the least. Great video, as always!
Hi Jack, I have 2 questions. 1. Can we do lazy loading on client components in Next 13 2. How to define fetch config segment wise? In docs it is mentioned but it doesn't work.
On #1 I don't think there has been any change since 12. So dynamic components. On #2 I honestly don't know what "fetch config segment wise" means. Do you have a link to the docs?
Does the code works? I'm having some TypeError: fetch failed when deploying a fork to Vercel. Edit: Only happens with Node v18, a downgrade to Node 16 has solved the issue
Thanks for this Jack! I was waiting for this video to drop. I'm sure you're expecting this question from many folks, but why not just use React Query? One clear win I see here is that the use hook can be called conditionally, so that works well for the individual Pokemon. Do you feel the use API is incomplete since it requires us to jump through hoops with creating our own cache or bringing in a 3rd party library?
Pros and cons. RQ has a ton of additional helpful features, but you can't call the hook conditionally. `use` on the other hand can be called conditionally, but is missing a ton of features. I'm just not sure conditional calling is enough of a win, but we shall see I guess.
@@greyu93 Definitely. I'm a huge RQ fan. I don't think `use` is in a place where it replaces RQ. Even if they put out `cache`, which would help remove at least this part. But RQ has a whole bunch of features that the core will never have.
Great video Jack, pointing out a pretty treacherous antipattern here. This idea just of the top of my head, I did not check it: if you wrap fetchData in useCallback (or the fetch promise in useMemo) and then "use" them, does that not limit the refetching?
This is a great video, ive fixed a few of my components now. Have you noticed any repeated Fast Refreshing, on my homepage which only has a hero and one other component that doesnt fetch anything im getting infinite fast refreshing and no idea why ?
@@NITRITOR interesting ill keep an eye out in my markup. i also noticed, stopping server, deleting .next dir and restarting server fixes the issue 99% of the time.
The return type of `fetch` is Promise. This is one way to coerce the return type of the fetch and then bring it through the generic type into the output of the cache.
@@jherr yes, I’m just saying that there’s no need to specify the generics in your function if you do it that way :) Your video was great though! I learned something new
@@Andyman2340 Gotcha. No problem, I'm glad you enjoyed the video. (Also, sorry if I came off a little grumpy I have Covid at the moment.) Anyway, I tested out removing the generic and it falls back on a type of `any` because the map has a type of `any` because I defined it like so `Map`. Now I guess I could have typed the map? But then I could only use the queryClient for one particular type of response, and so I'd need to create multiple queryClients. And I'd maybe have to also cast the fetch... I didn't try that.
I'm new devolper, so maybe i did not understand correctly!! could you please help me to understand this ? what if what we fetched from the API got changed ?! if you cach the promise in FatchMap and then do `use` on it will it fetch it again ?? AFAIK it will not and we will get the same data not the new one. do we need to invalidate this cach somehow ?
Do you mind explaining at (9:28) why/when the query method is needed instead of a simple fetch? And also, when should I consider using ReactQuery or SWR instead of this custom query?
When React function components are re-rendered the function is run from top to bottom. That means that every time the Home component is re-rendered it will create a new reference to a new fetch. This will send a new reference to use which will see it as a new promise and re-subscribe, which will force a re-render when it finishes. Which creates a new fetch with a new promise and the cycle will continue infinitely. React doesn't compare promises by implementation or by return type, it just compares them by reference. So that's why we need to cache the reference using the queryClient function (or some other mechanism). You should use React-Query or SWR for this. I'm showing this code here because people think they can just use `fetch` with use, which is not the case.
@@jherr ok I think I understand! So without the queryClient function, the data would load once, but when navigating on client side, it would still cause multiple fetches on every click, I guess?
@@edgarasben no, not every click. just all the time. it would just be an infinite loop that requires no user interaction. the return of one fetch would trigger a re-render, which would force another fetch, which would force another re-render and so on. Please try it for yourself to see if you can see the effect.
@@jherr as I understood, lifting the fetch outside component already solves the infinite loop problem even without the queryClient function:) But I will try! Thank you! :)
When ever i use MUI it ask for USE CLIENT. it makes it downlaod all mui javascript. Whole point of react become useless. Server side rendering work because of caching . now if you render it all in client ... you are writing 10000line code for 10 line code. TERRIBLE
True, at least in dev mode. In prod mode you should get tree shaking and theoretically only download the components that you actually use in that portion of the bundle. Also you can split out the bundle so that you have a vendor bundle that contains React and MUI so that the vendor bundle can be cached and the bundle that gets built for every route is much smaller.
@@jherr hey tks , now i proceed with making configureable side bar component using container css for sliding out screen. I want to make configurable component. Black box. Not white box like everyone hacking react . Only interface for component is properties. Every thing else for the component is self contained. Plug and play. Styles will be externalised. There will be some thing rigid but externalise properties so it can be customized. so if anyone read code for any page they should only few lines of code. I watched all react youtube videos. You all write too much code. its all unmaintainable. if anyone knows anything fully he will never talk about anything. We have the that desease. We only talk about things that is not perfect. if we know everything we might as well die. So fight is going on. i watch videos to find people thinking process. How they solve things in brief and efficient way. There is a beauty and perfection when people code less and do more. Also framework and api and everything change every 3 -6 month. I am trying to code things such a way its not framework dependent. I am only interested in good stuff from react. reducer is one bad idea in my opinion. In future people wont be coding but configuring from blocks. I want to get close to that using react ..take out most of the garbage and use it as dummy as much as possible.
Great video Jack. I am curious the way SWR worked was it would allow one to fetch data on the server attach it to a key. Then while paging to fetch more one could use the same key, and add data to the catch. With the whole server component & client component separation would we still be able to do that? or is there a different way to do things now when it comes to hydration?
@@NosherwanGhazanfar ah ok, you’d need a wrapper server component to make the first page request then pass that data onto a client component which would preload the cache with that first page of data and render it. Then have the client component manage the infinite scrolling.
I feel like the moral of the story here is to stick with React Query for client side in Next app/. I was hoping use() would replace it. :/ RQ is good, though.
Yeah, I didn't want to say that, but that's kinda my take as well to a degree. If `use` had come out first then we would likely still have needed RQ because `use` doesn't handle all the edge cases. The conditionality is nice though.
I know in frontend world, everything changes quickly, that's fine. But I can't get rid of this feeling, that the fetchMap cache is a straightener for a bender. I feel like it should be already included by default and the current behavior should be optional. On the other hand, maybe it would create even more confusion, so I don't know.
Now that promise trick fixes the infinite fetch requests, how about trying useContext inside that component and changing its state, it causes an infinite re render...
Agreed, that RSC is a key player in that regard. That is why e.g. Shopify adopted it in their Hydrogen framework, and eventually they are moving to Remix’s data loading pattern (instead of server components) as they see that will lead to faster performance and a simpler developer experience.
@@abdelhameedhamdy The Remix/Shopify/Hydrogen thing is verrrry interesting. After having played with Hydrogen a little bit, lemme just say that I'm happy for potential Shopify third party devs that they bought Remix.
Hey Jack, I made a video last week about Next 13 and when I watched yours, I was scared!!! Here's the moment: th-cam.com/video/NYMbugWuXRk/w-d-xo.html So I came back to it and checked the code again: I don't got any loop. Is it because I don't use "use" from react? Is it related to this hook? Thanks for this video though. Best, Guillaume
Great video Jack, as a Javascript beginner I can't help but think as soon as you add Typescript it makes everything less readable and makes the functions look overly complicated. Just as i thought I was understanding Javascript I am getting discouraged by Typescript because this seems to be the trend that employers want and it is just to hard for a beginner
That’s a tough one because when I put out a video on TS I get folks saying “why not JS”? And vice versa. But I thought TS was better in this case especially since NextJS is now defaulting to TS.
This way of using a Map and store all promises and never free them will lead to a memory leak. Be very careful if you using code like this in a prod system.
yeah, as for the moment, the "use" and "fetch" combination should not be used in client components at all, unfortunately rendering the code used in this video complete antipattern. I hope this changes in the future tho
Man, I have so much respect for you, admire you really... do you really need the tiktok-level-cringe cover pictures? You're so far above this. Love you buddy.
Ok... Feel free to jump on the BCC Discord and explain the issue in a lot more detail and someone may jump in and help you out. Please READ and FOLLOW the #rules before posting.
I use above and i am making one call in developer tools screen. no infinite loop useEffect(() => { const fetchTable = async (tablename) => { setPageState(old => ({ ...old, isLoading: true })) var url=``;
you are doing a good job on your useEffect dependencies. when the dependencies are scalar values (strings, booleans, or numbers) they are compared by value and thus won't trigger the infinite loop that you would see if you just had a dependency on `pageState`. Since `pageState` is an object and you would be changing the reference to that object on each iteration.
16:40 Jack small improvement you could make here. Instead of `typeof pokemon[0]` you can use `typeof pokemon[number]` which will get the shape from all objects in the array, not just the first one :)
Awesome! Love it!
Thanks a lot! Was frustrated with this error and thankfully saw this video.
Great video! It also makes a bit clearer why React Query works the way it does and some of the decisions that went into it. Amazing stuff as always
This explanation saved my day, I couldn't find anywhere how to solve this rendering problem in next 13.4, thanks jedi
Thank you so much for this, I spent so much time just to do client-side data fetching & even Next.js 13.2 didn't fix this yet.
Thank you for the solution. Was experiencing this issue even when using server components, decided to switch to client components for now.
I just want to say thank you so much! I watched your React State Management on FCC and learned so much!
wow, mind blown, i only see basic coding on youtube but finally found you so i can learn some advance stuff and level up my coding skills.
The RFC about ‘use’ really helped me overcome this issue .Yet another great video Jack
Use swr or react-query for now
That's really bad. I feel like this is a bug, because it would mean that you cannot use code that is not written with NextJS in mind. Calling fetchData() directly (as long as the its arguments is stable) in vanilla React works as intended.
Yep, same here. I was dreading having to hear the word "memoize" because if we are getting to that (and we are creating the same kind of behaviour here), it just seems convoluted at that point.
But this begs the question. What is NextJS doing to React Components that are rendered client side, compared to vanilla React? It seems odd that they would have different semantics.
They aren't doing anything different with the client side components over regular React. They are just allowing only certain components to be marked as client side so only those components need to be hydrated on the client. Which is, potentially, a big improvement in time to interactive.
@@jherr Yeah I understand that, but the behavior of "use" is different between Vanilla React and Next as shown in the video.
@@dealloc I don't think so. I saw this exact same issue with the experimental branch of React after the RFC came out but before NextJS 13 got released.
Its stuff like this that makes me so happy react query exists. Jeez, I haven't had to think of caching promises in a very long time.
Awesome content! I really appreciate the tasteful abstractions you seamlessly create when talking about a topic. Thank you!
The official document says fetch api(the special fetch api used for server components) doesn't support client components yet ! which means the infinite loop can happen like that. They recommend to use swr or react-query in client components !
thanks man. info like this does help.
Now it makes sense, probably use( ) uses useState inside it's implementation, that's why it triggers another rerender. Man you're awesome !!
It would be nice if you could make a separate video covering all important changes to Next 13 :)
I mean.. Man, there's already content for it, like this th-cam.com/video/_w0Ikk4JY7U/w-d-xo.html and this th-cam.com/video/__mSgDEOyv8/w-d-xo.html, but I guess you want to hear those changes from Jack
It's fascinating to see the patterns of old PHP emerging in React with server components. Reminds me of the 'the loop' in WordPress where you loop over 1 DB query result then for each given item fire off a load more DB requests to render a template. I wonder if this pattern could encourage a lot of n+1 issues. Do you know if it's possible to use something like dataloader within react server components?
N+1 can happen anywhere. That's just experience that leads you to an understanding that N+1 is a site killer.
Not sure if the generics in QueryClient is getting used if we do an `as `.
They definitely are. Otherwise the output of the fetch is Promise so the generic is . You have to type the promise for the generic to do anything useful.
Hey Jack. Thank you for doing this and the use hook clearly has potential to be a real ugly foot gun. I'm sure most people wouldn't want to create their own promise cache like this. You also probably want to be able re-fetch, retry requests, invalidate the cache etc. All of which is built in to for ex react-query. Could you maybe do a video of how to use react-query with the use hook and server components? Or will there be other tools to support the "new" Next 13 way of doing things?
React team will create an RFC for a cache solution. They mention it in "use" RFC -> "a separate RFC will introduce an API called cache to assist with caching data. Taken together, these proposals will unlock official support for Suspense for Data Fetching."
I'm guessing that solution will mostly be used by libraries that you would consume. Maybe Next.js team will do their own solution based on that cache API, who knows.
I second the call for a video about using React query with next 13
I'll roll RQ into a video on NextJS 13 layouts and RSCs. How about that?
@@jherr you're the man. Thank you!!! :)
Learned so many things from just one video!
Great video! Thanks for this Jack!
I just felt that next js 13 is a step back to create react app, next js 12 was awesome
I think the RSC thing could be a nice win. That's the async component rendered server side only with zero hydration. But... the `use` thing, I'm not sold on.
We will still be able to do the equivalent of getStaticProps at the highest page level in the component tree, but this time we can also do more - like get global props, or specifically nested component fetching.
There is still a fair amount to work out, if you are looking at this now, you are ahead of the curve, lets see how it works out when the dust has settled a bit and standard approaches have risen
This looks very much like how tRPC does it. Thanks for this video, Jack!
This issue is being said in beta docs. You’re enforcing to use swr or react-query instead.
Ya I saw it in the docs too
Jack your content has top notch quality.
I am curious, how you keep yourself up to date.
That's really tough. I read a lot. I keep lists of things I want to investigate more into. I have a lot of connections that contact me when things happen. And there is Tech Twitter.
Had this exact problem
This vid answers my questions
Thank you
i like this video a lot. love the custom queryClient.
Love the videos. Have one question though, and I've tried searching for answers, but the ones I've come across seem pretty surface level so I'm asking here
At around 12:55, you mention that it's very similar to the useSwr hook from swr, and since I'm already using that, what's the point of React's use hook for me? UseSwr already does conditional fetching (it's not pretty but it does it), and a lot of the behaviours that the new React hook bring seem to be already available with useSwr.
Maybe the new hook just doesn't bring new things that I need?
The `use` hook is not specific to fetching data. Its purpose is to bring async/await (in general, not only fetch) into React. However it does not (currently) bring cache invalidation, and won't deal with mutations or optimistic updates like React Query and useSWR.
Ah this is eye opening!.. Thanks Jack
Отличный материал. Спасибо за вашу работу!
Добро пожаловать.
@@jherr добро пожаловать is welcome, but in like "welcome here", not "you are welcome" :) right one is "пожалуйста" which is confusing in it's own way, because it also means "please" :)
@@JLarky Hahah. Ok. гугл переводчик отстой (google translate sucks)
@@jherr truer words have never been said :-)
You set up generics for QueryClient, but then you cast it instead of interacting with the generic. What's the point of setting up the generic then if you're just gonna cast it?
I was just commenting on this
still a great example
He's casting the output of the fetch promise and the QueryClient generic is inferring from the output.
What Luke said. :)
note to self: Seen half @9:30, will see the rest later. Good logic to understand.
Best of the best.❤ Thank you!
I appreciate your content. Was so useful for me.
I think it will be some time before I adopt this new hook into any codebase I work with at my job.
IMHO, the RSC replacement for getServerSideProps and getStaticProps (although there is still static paths as a function) is a definite improvement over 12. I'm a lot less sold with `use` on the client.
Excuse my ignorance… I’m trying to understand in what scenario this pattern would be necessary? Why not just fetch from a server component and pass the data down as props to a client component that handles the interactivity? Or if you must do the fetching on the client side, do it in a useEffect hook that depends on the Pokémon selected in state? That way the component renders once then useEffect makes the fetch and then only does a new fetch when the Pokémon selection changes in state.
You can certainly do that, and I would recommend that, or using react-query or swr, over using use. This video was really meant to say; hey, if you are going to do this, then watch out because of the side effects.
Really appreciate what you're doing. Thank you :)
is it wrong if the function fetchData does not return a promise, but instead the resolved "value" ?
const fetchData = async () => {
...
return await res.json();
};
Depends on what the JSON. If it's an array or an object then yes because it's a reference and the reference will be new each time and React uses references for comparison. Even if the contents of the array or object are the same it doesn't matter. If the result is a scalar value (string, boolean or number) then the data will be compared by value and if the values are the same then the loop will be broken.
@@jherr thank you
Great video, I was going crazy about how to fetch data in client components. Also, what would you do if you want to persist the id in the url and get it from there? Would you trigger a router push from the client component, then the parent (server component) will catch that paran and re fetch and pass the data as a prop to the client component? Or client component can listen to changes in url? I’m a little confused about that. Thanks!
Thank you for these videos :)
22:46
Isn't it not a proper factory function? As far as caching concerned it will create a new separate map each call. So it has to be a singleton one way or another.
But how do you do client-side singletons with the new app structure?
If used properly NextJS 13 is still a client-side SPA after the first page fetch.
@@jherr
Yeah but NextJS 13 announcement didn't tell how do you get an equivalent of "global" client-side wrappers similar to the ones in the `_app` file in the old system. And the closest thing to an answer was in the Q&A stream and was along the line of "just put it in your highest possible client component, bro".
Client wrappers now have to be inside client components, but because client components are completely ignored by the server context, it's not possible to set up a system where a client context wraps a server-rendered page and then hydrates itself client-side.
@@ra2enjoyer708 Yeah, the client side stuff needs to be leaf nodes... Sigh. The great thing about all this complexity is that NextJS is far and away the most popular React platform, and so, if we can all figure out some good best practices around this stuff, we will all have jobs for a long time. :)
great job . i got this warning yesterday. i try nextjs 13 but information not enough in web . i hope you will post more info about nextjs 13 Thank you.
Great stuff Jack, as always. Cheers
Thx for the video. Should we combine NextJS 13 with Express to improve app?
Hi Jack, there's one thing that seems bizarre to me. In your example of calling the hello API, why is it visible in the browser network tab? It appears to be called twice, once on the server side and again in the browser. What's the purpose of this? Shouldn't it only be called once on the server, since it is equivalent to getServerSideProps?
Can you give me a time reference? I know this video isn't super old, but I've forgotten exactly what I was doing. I'm sure I knew what I was doing, or I didn't, whichever. :) I'll clarify it for you.
@@jherr 9:17 - I've followed along and found out that the request is made on the server as well as on the client side. When using getServerSideProps (old way, in pages directory), request is sent only on the server side, as expected.
Thanks for your great channel, love the amazing content
I really don't understand. Do we have to use the "use client" directive to avoid the infinite loop request? So, what do you need to do in the server component?
I wondering whether this query client will cache result for all of the users or for a single user? How?
Use is client side, so it would be for a single user, well, browser instance.
@@jherr Thanks!
how when i need params.slug in fetch?
How about stale data ? Any update on revalidation Jack?
You can remove the request key from the map and the re-render to get new data.
In the example in the video, if Pokemon data changes in the BE and I already have it in cache, the only way to revalidate is to delete Pokemon key from the map when I want latest data ?
@@ayushjain7023 Correct. Which is what RQ and SWR are going to do as well. It's just in your hands when using `use`.
You are an OG of JS ❤️
According to video "use" is a react hook. But there is no such hook in react docs. Why?
It's currently just documented in the RFC, and is available in the current experimental tags of react and react-dom, as well as next@latest.
Hi Jack, thank you for the great content, but what happened with the TypeScript Design Patterns series? You mentioned you were going to cover all the GoF patterns?
I'll get there eventually. :)
@@jherr looking forward to it! Thank you for producing this content!
I also had the same problem, thanks a lot
the master react teacher no doubt!
When have Pokemon become the goto for devs for little API-test-sites?? Is this necessary? Aren't there a million other possibilities... ? I see this everywhere and it is quite annoying to say the least.
Great video, as always!
Hahah, it's innocuous, and fun, and if we use the screen in the thumbnails then it's pretty too.
@@jherr I am probably just too old :D
Learning A LOT from your videos though, thanks for sharing Jack
Hi Jack, I have 2 questions.
1. Can we do lazy loading on client components in Next 13
2. How to define fetch config segment wise? In docs it is mentioned but it doesn't work.
On #1 I don't think there has been any change since 12. So dynamic components.
On #2 I honestly don't know what "fetch config segment wise" means. Do you have a link to the docs?
Does the code works? I'm having some TypeError: fetch failed when deploying a fork to Vercel. Edit: Only happens with Node v18, a downgrade to Node 16 has solved the issue
Thanks for this Jack! I was waiting for this video to drop. I'm sure you're expecting this question from many folks, but why not just use React Query? One clear win I see here is that the use hook can be called conditionally, so that works well for the individual Pokemon. Do you feel the use API is incomplete since it requires us to jump through hoops with creating our own cache or bringing in a 3rd party library?
Pros and cons. RQ has a ton of additional helpful features, but you can't call the hook conditionally. `use` on the other hand can be called conditionally, but is missing a ton of features. I'm just not sure conditional calling is enough of a win, but we shall see I guess.
@@jherr, in the react-query call, you can 'disable' the fetch with an 'enabled' option and run it once some variable tells it to do so.
@@greyu93 Definitely. I'm a huge RQ fan. I don't think `use` is in a place where it replaces RQ. Even if they put out `cache`, which would help remove at least this part. But RQ has a whole bunch of features that the core will never have.
@@jherr totally agree! You're doing amazing work for us, a world is a better place thanks to you :D
Great video Jack, pointing out a pretty treacherous antipattern here. This idea just of the top of my head, I did not check it: if you wrap fetchData in useCallback (or the fetch promise in useMemo) and then "use" them, does that not limit the refetching?
I could't get that to work. Conceptually, yes, that should work.
cant we use AXIOS for next.js 13 bcz all examples use FETCH apis? and why r u not using arrow function components
This is a great video, ive fixed a few of my components now. Have you noticed any repeated Fast Refreshing, on my homepage which only has a hero and one other component that doesnt fetch anything im getting infinite fast refreshing and no idea why ?
I usually get those when I'm rendering invalid html, such as a button inside another button and stuff
@@NITRITOR interesting ill keep an eye out in my markup. i also noticed, stopping server, deleting .next dir and restarting server fixes the issue 99% of the time.
What vs-code color theme are you using?
Why have you gone back to iTerm, rather than sticking with Warp?
Actually I'm trying out Tabby right now 🤯.
Using “as” in TS is coercing the value, it’s not using the generic.
You need to format the function like: queryClient(“hello”, () => { …stuff })
The return type of `fetch` is Promise. This is one way to coerce the return type of the fetch and then bring it through the generic type into the output of the cache.
@@jherr yes, I’m just saying that there’s no need to specify the generics in your function if you do it that way :)
Your video was great though! I learned something new
@@Andyman2340 Gotcha. No problem, I'm glad you enjoyed the video. (Also, sorry if I came off a little grumpy I have Covid at the moment.)
Anyway, I tested out removing the generic and it falls back on a type of `any` because the map has a type of `any` because I defined it like so `Map`.
Now I guess I could have typed the map? But then I could only use the queryClient for one particular type of response, and so I'd need to create multiple queryClients. And I'd maybe have to also cast the fetch... I didn't try that.
Hello Jack, great content ! Do you know if on-demand revalidation has changed in Next 13 ?
I don’t think so. It wasn’t mentioned in the blog post.
I'm new devolper, so maybe i did not understand correctly!!
could you please help me to understand this ?
what if what we fetched from the API got changed ?! if you cach the promise in FatchMap and then do `use` on it will it fetch it again ?? AFAIK it will not and we will get the same data not the new one.
do we need to invalidate this cach somehow ?
Yeah. You would need to invalidate the cache. Or reload the page, which would flush the cache.
Do you mind explaining at (9:28) why/when the query method is needed instead of a simple fetch?
And also, when should I consider using ReactQuery or SWR instead of this custom query?
When React function components are re-rendered the function is run from top to bottom. That means that every time the Home component is re-rendered it will create a new reference to a new fetch.
This will send a new reference to use which will see it as a new promise and re-subscribe, which will force a re-render when it finishes. Which creates a new fetch with a new promise and the cycle will continue infinitely.
React doesn't compare promises by implementation or by return type, it just compares them by reference. So that's why we need to cache the reference using the queryClient function (or some other mechanism).
You should use React-Query or SWR for this. I'm showing this code here because people think they can just use `fetch` with use, which is not the case.
@@jherr ok I think I understand! So without the queryClient function, the data would load once, but when navigating on client side, it would still cause multiple fetches on every click, I guess?
@@edgarasben no, not every click. just all the time. it would just be an infinite loop that requires no user interaction. the return of one fetch would trigger a re-render, which would force another fetch, which would force another re-render and so on. Please try it for yourself to see if you can see the effect.
@@jherr as I understood, lifting the fetch outside component already solves the infinite loop problem even without the queryClient function:) But I will try! Thank you! :)
@@edgarasben yeah, that fixes it as well. the queryClient abstraction makes this externalized cached fetch easier to manage.
When ever i use MUI it ask for USE CLIENT. it makes it downlaod all mui javascript. Whole point of react become useless. Server side rendering work because of caching . now if you render it all in client ... you are writing 10000line code for 10 line code. TERRIBLE
True, at least in dev mode. In prod mode you should get tree shaking and theoretically only download the components that you actually use in that portion of the bundle. Also you can split out the bundle so that you have a vendor bundle that contains React and MUI so that the vendor bundle can be cached and the bundle that gets built for every route is much smaller.
@@jherr hey tks , now i proceed with making configureable side bar component using container css for sliding out screen. I want to make configurable component. Black box. Not white box like everyone hacking react . Only interface for component is properties. Every thing else for the component is self contained. Plug and play. Styles will be externalised. There will be some thing rigid but externalise properties so it can be customized. so if anyone read code for any page they should only few lines of code.
I watched all react youtube videos. You all write too much code. its all unmaintainable.
if anyone knows anything fully he will never talk about anything. We have the that desease. We only talk about things that is not perfect.
if we know everything we might as well die. So fight is going on.
i watch videos to find people thinking process. How they solve things in brief and efficient way. There is a beauty and perfection when people code less and do more.
Also framework and api and everything change every 3 -6 month. I am trying to code things such a way its not framework dependent.
I am only interested in good stuff from react. reducer is one bad idea in my opinion.
In future people wont be coding but configuring from blocks. I want to get close to that using react ..take out most of the garbage and use it as dummy as much as possible.
Great video Jack.
I am curious the way SWR worked was it would allow one to fetch data on the server attach it to a key.
Then while paging to fetch more one could use the same key, and add data to the catch. With the whole server component & client component separation would we still be able to do that? or is there a different way to do things now when it comes to hydration?
Same way. You’d pre populate the map with the first page and then add onto it as the customer scrolls.
@@jherr in the server component
@@NosherwanGhazanfar ah ok, you’d need a wrapper server component to make the first page request then pass that data onto a client component which would preload the cache with that first page of data and render it. Then have the client component manage the infinite scrolling.
@@jherr that makes sense 👍🏽
If i try to use context in an async server component, my app goes in infinite loop. Have you some suggestions?
You can't use context or hooks in a React Server Component.
@@jherr not directly, or not at all?
@@LorenzoSemorile Not at all. You have to use `useContext` to access context and that's a hook, and you can't use hooks in React Server Components.
We’ve got too many experimental APIs out at the same time
I feel like the moral of the story here is to stick with React Query for client side in Next app/. I was hoping use() would replace it. :/ RQ is good, though.
Yeah, I didn't want to say that, but that's kinda my take as well to a degree. If `use` had come out first then we would likely still have needed RQ because `use` doesn't handle all the edge cases. The conditionality is nice though.
I know in frontend world, everything changes quickly, that's fine. But I can't get rid of this feeling, that the fetchMap cache is a straightener for a bender. I feel like it should be already included by default and the current behavior should be optional. On the other hand, maybe it would create even more confusion, so I don't know.
"straightener for a bender" has now entered my lexicon! Thank you so much!
Now that promise trick fixes the infinite fetch requests, how about trying useContext inside that component and changing its state, it causes an infinite re render...
I still like the Remix style, and the islands notion as well in Deno and Astro.
Me too. But I'm open to the idea that the RSC stuff, in prod mode, could make a big difference in time-to-interactive.
Agreed, that RSC is a key player in that regard. That is why e.g. Shopify adopted it in their Hydrogen framework, and eventually they are moving to Remix’s data loading pattern (instead of server components) as they see that will lead to faster performance and a simpler developer experience.
@@abdelhameedhamdy The Remix/Shopify/Hydrogen thing is verrrry interesting. After having played with Hydrogen a little bit, lemme just say that I'm happy for potential Shopify third party devs that they bought Remix.
It wouldn’t be React without footguns!
which vscode theme you are using?
Night Wolf [black]
Why the... why are we trying to prevent the fetch from refetching instead of preventing the component from reinitializing???
Just experience dthis infinite loop issue my self right now with my use client component then found this video hehe
22:30 this cracked me up 🤣🤣🤣🤣
why not "import {cache} from 'react'"?
I thought cache was still in RFC.
In React 18.2.0 it's not even behind an experimental flag 🤷♂
Click bait part starts at 6:14
Thanks!
Спасибо!
Thank you so much!
Great tutorial 🧑💻
Hey Jack, I made a video last week about Next 13 and when I watched yours, I was scared!!!
Here's the moment: th-cam.com/video/NYMbugWuXRk/w-d-xo.html
So I came back to it and checked the code again: I don't got any loop.
Is it because I don't use "use" from react? Is it related to this hook?
Thanks for this video though.
Best,
Guillaume
My bad my friend my example wasn’t on client side 😅
Phew. Yeah I just checked your video (which is excellent) and yeah, that’s an RSC.
@@jherr wow jack thank you so much it makes me very happy - huge fan of your work. Please continue. Best, Guillaume
Great video Jack, as a Javascript beginner I can't help but think as soon as you add Typescript it makes everything less readable and makes the functions look overly complicated. Just as i thought I was understanding Javascript I am getting discouraged by Typescript because this seems to be the trend that employers want and it is just to hard for a beginner
That’s a tough one because when I put out a video on TS I get folks saying “why not JS”? And vice versa. But I thought TS was better in this case especially since NextJS is now defaulting to TS.
nice!
This way of using a Map and store all promises and never free them will lead to a memory leak. Be very careful if you using code like this in a prod system.
Depends on how many "unique" requests you have. You could also do an LRU here if that was a major issue.
next site : "Wrapping fetch in use is currently not recommended in Client Components and may trigger multiple re-renders."
yeah, as for the moment, the "use" and "fetch" combination should not be used in client components at all, unfortunately rendering the code used in this video complete antipattern. I hope this changes in the future tho
I'm First commentor, drop a like in here lol. Great tutorial in whole YT💯
Woooooow!!
Man, I have so much respect for you, admire you really... do you really need the tiktok-level-cringe cover pictures? You're so far above this. Love you buddy.
Fair. We did one without it. But the CTR is always better with the cringy faces. 😢
@@jherr ❤
Man this feels.. kinda weird.
not working
Ok... Feel free to jump on the BCC Discord and explain the issue in a lot more detail and someone may jump in and help you out. Please READ and FOLLOW the #rules before posting.
I use above and i am making one call in developer tools screen. no infinite loop
useEffect(() => {
const fetchTable = async (tablename) => {
setPageState(old => ({ ...old, isLoading: true }))
var url=``;
//await fetch(url, {method: 'GET'})
await fetch(url)
.then((response) => response.json())
.then((json) => {
//const data=json[data]
setPageState(old => ({ ...old, isLoading: false, data: json.data, total: json.total}));
}).catch(error => console.error('timeout exceeded'));
fetchTable('tablename');
}, [pageState.*])
you are doing a good job on your useEffect dependencies. when the dependencies are scalar values (strings, booleans, or numbers) they are compared by value and thus won't trigger the infinite loop that you would see if you just had a dependency on `pageState`. Since `pageState` is an object and you would be changing the reference to that object on each iteration.
This is why react effects are a bad abstraction. Angular and lit solve this elegantly by not trying to be cool.
ᵖʳᵒᵐᵒˢᵐ ⭐
bruv?????????
How react got popular when its so poorly designed is beyond me.
i hate the long intro. I just want to hear what the issue with the code is. dislike