Hi guys, I'm using next app router, the lastest version, and I have the following problem.
I have a route, and also a directory that is the following structure: "market/[slug]/[id]" and inside them I have a page and layout and both async component and have a getData function to get the data of the component, the problem is when I change the slug or the id, both function are call's and I need to call only the getData of the page.
#Layout and pages
55 messages · Page 1 of 1 (latest)
🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord
🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize
✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)
normally you shouldn't fetch data inside your layout. So remove it please. If you removed it: which error do you get or which feature is gone? Then we can fix it @pale marten
The layout one shouldn't fire right? Did you use cache to deduplicate calls?
The layout shouldn’t make data fetches. Even with cache
why?
if data is shared across pathes I don't get what's the problem
It's to long for this one message. So please read the message.txt
Yeap, the layout only has to be called once, when the component is mounted
yea, then please follow this advice: #1179819042182279168 message
The problem is that I need like a shallow since once I update one of those params, all the getData will be called again
you can revalidate the data. When you revalidate it, also the jsx will be refreshed
you can see how the jsx get's updated after revalidating: https://youtu.be/dDpZfOQBMaU?si=AZZRPfGenuJiAOqN
is that generated? For instance "Moreover, passing data between a parent layout and its children is not possible." seems false ?
"Because this file is not a Page, you cannot use getStaticProps or getServerSideProps" this is a Page Router concept
in App Router you just fetch your data, and it's possible in a layout, because the App router wraps routes with a top level suspense
"Layout components do not receive the searchParams prop and are not re-rendered during navigation. This could lead to stale searchParams between navigations" relevant only if using searchParams
searchParams is bad in pages too anyway but that's another topic
"Instead, you can use fetch or React cache in the component that needs the data without worrying about the performance implications of making multiple requests for the same data " this one is true when sharing data with RSCs but not from server to client
if client components need the data, you'll want to setup a React context within the layout too
so honestly I find this take that layout shouldn't fetch data quite debatable
Not sure I follow, what's the problem about calling getData again? If you navigate and the params changes, you need data relevant for this param right?
I think it's not a good recommendation to just tell "hey fetch in layout" when they CAN be bugs with it in the future. I don't mean bug like technical bugs, I mean bugs like "oh I don't know this bla bla". So you normally fetch all the stuff inside the page.js (which are also getting the dynamic data) and work with it there
I mean I agree that layouts in Next are weird to say the least
and can have suprising behaviour
namely because they don't rerender while in most other React framework a layout is something that do rerender on page change (but do not remount while pages both mount and render)
hence the searchparams issue etc.
however you can't really say that one should not fetch data in layouts, that's just not true
fetching in pages will overfetch if you get the same data in different page
of course you CAN do that, like I mentioned, but it's not the prefered case:
In conclusion, while it's technically possible to fetch data inside a layout, it's generally not recommended due to the potential for stale data and ...
something called "cache" exists. And in nextjs more then one cache
cache is scoped to the request
it deduplicates data fethcing within the same page
but never across pages
across pages you could use an in-memory cache or whatever but then you have to be super careful with user specific data
I still don't get where you got this recommendation honestly
(trying to think about it honestly because I know layouts are tough, not arguing just for the sake of arguing, I may perfectly miss a point ^^ )
it doesn't
you can take a look at this: https://nextjs.org/docs/app/building-your-application/caching#request-memoization
There is no different, if you call it 2 times or 100 times. It's inside the memoization
you think there ar 6 B request and 2 A and 3 C requests?
In total 11 requests
nooo there are just 3 ^^
It's called ✨ cache ✨
Right, the problem is the following,
I have the following structure: market/[slug]/[id], In the first time I need to fetch some data that are the filters, and then with another fetch I have to get all the products with pagination and the filters that I applied (Filters change the url with a router.push). But when this happen, the filters and the products call again since the url has been changed by the filters, And I only need to fetch the product but not filters.
Yes, and it caches per request, the fetch calls you see happens in the same request/response roundtrip... not across different requests/pages
Great thanks
ok I get the idea
but I don't get why your layout fetches again?
is the layout at [id] level or [slug] level?
At the [id] with page
can you move the filter fetching higher up?
Also I'm using axios instead of fetch
if it doesn't change per id, it should be fetched in a layout upper in the tree
Ok, I will try it
shouldn't make a difference if axios uses fetch under the hood, which I think it does (but not sure)
Yes I think so.