#Client Side Data Loading
45 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)
I would recommend to use server components and then you can super simple fetch the data.
If you need it in a client component i would fetch it in a server conponent and give the props to tge client component
the problem is this pattern breaks doesn't work when you have a client component that needs to render another data-fetching component
since you can't have a server component be a child of a client component
You can do slots and conditional rendering based on url hardcoding a client component into a template and then having the child be a route but this becomes insane quickly
well then if you don't want to have server component slots in ur client side component, then yeah use react query
well its that slots aren't meant for tightly coupled nesting (e.g. when the parent component passes props about what to fetch to the client)
Like you have a parent component get a list of departments, and then have each row in a table show a few courses. The row component ideally fetches its own data based on the department id you pass in as a prop
Maybe I have the wrong architecture overall and should do fetching of large objects and pass them down instead of multiple round trips but I'm not sure. feels like the beneift of react is having logic (including CRUD) colocated with the presentation layer on each chunk of the app
ok sure have ur slot accept a function that renders a reactnode
type Props = {
course: (courseId: number) => React.ReactNode
}
const NestedServerSideComponent = ({courseId}: {courseId:number) => <div>{courseId}</div>
const ClientSideComponent = ({course}: Props) => {
const id = 5
return course(5)
}
const ParentServerSideComponent = () => <ClientSideComponent course={(courseId) => <NestedServerSideComponent courseId={courseId}/>} />
I'm actually not entirely sure how the server component would fetch server side first if the courseId is given client side.. maybe it works maybe it doesnt eh
yeah I think you want sth like https://relay.dev/ where u can define the dependencies for each component but all the fetching is done in a big blob at the top
pre sure nextjs fetch caching sth sth can do what ur after but i'm not too sure
you could do weird stuff with query params, other url statefulness, or even like cookies (basically any way to encode state outside of react in a way that gets sent to the server so that the server can then figure out what to render for a client) but the ideal situation would be that there is a way to have a data loading framework capability that lives on the server and can pass data to the client component as well as other child components
i mean a rudimentary solution would be to have a context that fetches and then use that
wdym a context?
like react context
yea but that doesn't live on the server
yeah ur right i guess there rly isnt anything for stuff like this yet huh
I mean what u could do
is fetch everything in the top level server component
its cached
then in every child component use the same fetch call
use typescript to filter out and specify for only that component's dependencies
instead of
function Page() {
return <Table />
}
"use client"
function Table() {
return everything
}
use
function Page() {
return (
<Table>
<TableHeader>...</TableHeader>
<TableRow>...</TableRow>
...
</Table>
)
}
then Table can be a client component while TableHeader and TableRow can still be server components if you want
ok but what if I want table to have some related text that depends on the number of rows the table has. Table needs to pass a prop into that component so it knows what table it is or at least how many rows it has. I'd prefer to just be able to pass some sort of table id into this component and it figures out the number of rows itself
times like this is when I wanna use webflow for the landing page and then just use next fully client side as an overweight routing library
I don't think this works because props need to be serializable afaik and functions aren't
yeah this then
async function TableRowCount({ id }) {
const count = await getRowCount(id);
return count;
}
function Page() {
const id = getFromSomewhere()
return (
<Table>
<TableHeader>...</TableHeader>
<TableRow>...</TableRow>
<TableRowCount id={id} />
</Table>
)
}
this design pattern doesn't scale
if a component needs something, the data that it needs must be available to it. in your case, the number of rows component needs the entire row data. so all rows have to be fetched in a server component above it. so you fetch all rows above it and pass the data via props.
this is just how server-side rendered apps work. none of this is related to nextjs.
making parent components aware of client components is exactly what I'm trying to avoid
well whatever you do. this is a hard truth you must deal with.
you need the total number of rows, you have to fetch it somewhere up the tree. could be just a sql COUNT, but could also be simply fetching all rows and pass that object as a prop.
(about getServerSideProps: it's equivalent to the option of fetching everything in the root server component and then pass it as props to children components, by the way. it won't do better than what we have here.)
feel like you are just asking for something that's theoretically impossible
The thing is I don't need the total number of rows (list of courses), I just need some piece of information that will let me get the total number of rows (department id). This isn't a components must be able to know what data render without passing it in issue, it's a components should be able to get the data they need to render based on piece of information that is passed in.
prob not impossible. Would need to just make explicit the type of data that a child expects, fetch/create it in a server side data function, pass that data to the server side data function of the child component as well as to whatever the current component components needs for its own non-child rendering, and then associate which call of the child data fetch/render function was assocaited with which call of the parent data function to slot the child component in
the problem is this creates a data waterfall which becomes inpreformant without enough prefetching based on expected values (sort of what @brave osprey was talkin about)
the original question wasn't even really about this kind of stuff (even though its related), it how can you have a client function fetch data (efficient in terms of loc not anything else) so that you didn't need to make a slot to render it
i really don't understand what you are trying to do, so i won't be able to provide more help other than the interleaving link above.
just gonna say this:
- server components are simply () => html functions
- they cannot be imported to client components because they don't run on the client
- they may be rendered as children or other props of client components completely fine
- client components cannot pass props to server components, but data can be passed from the client to the server by way of URL query params.
This became a discussion about initial data fetches that depend on some parameters, but the original question was about if there was a way to load data into client components that isn't wrapping them in a server function so that for child client components you don't have to also wrap them in a server component and then use slots and can just directly import the child component. It sounds like there isn't and you have to use slots, not have client components, or not have server components and fetch data fully client side