Layout and pages
Unanswered
Common carp posted this in #help-forum
Common carpOP
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.
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.
54 Replies
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 @Common carp
The layout one shouldn't fire right? Did you use cache to deduplicate calls?
@Eric Burel The layout one shouldn't fire right? Did you use cache to deduplicate calls?
The layout shouldn’t make data fetches. Even with cache
if data is shared across pathes I don't get what's the problem
Common carpOP
Yeap, the layout only has to be called once, when the component is mounted
@B33fb0n3 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 <@449711286650011658>
Common carpOP
The problem is that I need like a shallow since once I update one of those params, all the getData will be called again
@Common carp 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
@Common carp 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 see how the jsx get's updated after revalidating: https://youtu.be/dDpZfOQBMaU?si=AZZRPfGenuJiAOqN
@B33fb0n3 It's to long for this one message. So please read the message.txt
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 conceptin 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 searchParamssearchParams 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 clientif 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
@Common carp The problem is that I need like a shallow since once I update one of those params, all the getData will be called again
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?
@Eric Burel 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 ...
@Eric Burel fetching in pages will overfetch if you get the same data in different page
something called "cache" exists. And in nextjs more then one cache
@B33fb0n3 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
@B33fb0n3 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 ...
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 ^^ )
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
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
In total 11 requests
@Eric Burel 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?
Common carpOP
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.
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.
@B33fb0n3 nooo there are just 3 ^^
It's called ✨ cache ✨
Yes, and it caches per request, the fetch calls you see happens in the same request/response roundtrip... not across different requests/pages
Common carpOP
Great thanks
but I don't get why your layout fetches again?
is the layout at [id] level or [slug] level?
Common carpOP
At the [id] with page
can you move the filter fetching higher up?
Common carpOP
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
Common carpOP
Ok, I will try it
@Common carp Also I'm using axios instead of fetch
shouldn't make a difference if axios uses fetch under the hood, which I think it does (but not sure)
Common carpOP
Yes I think so.
I will move the layout to a higher level and then I will tell you