recommended fetch pattern for data shared by multiple client components in app router
Unanswered
Champagne D’Argent posted this in #help-forum
Champagne D’ArgentOP
after reading https://nextjs.org/docs/app/building-your-application/data-fetching/patterns and https://nextjs.org/docs/app/building-your-application/rendering/composition-patterns#sharing-data-between-components, I feel like I'm seeing two contradictory recommendations.
I initially would fetch data from a server component that would pass down the data two its two child client components and found that the json data, even though parsed in the server component shows up in the client components as strings, which means that I'd have to parse it yet again in the client components. This seems to be what's recommended in the first link.
then I see that it might be discouraged to follow this pattern according to the second link and instead use nextjs's fetch, which may lead to something like this
in both client components that would use that same data since it would be cached. which pattern is actually recommended here?
I initially would fetch data from a server component that would pass down the data two its two child client components and found that the json data, even though parsed in the server component shows up in the client components as strings, which means that I'd have to parse it yet again in the client components. This seems to be what's recommended in the first link.
then I see that it might be discouraged to follow this pattern according to the second link and instead use nextjs's fetch, which may lead to something like this
useEffect(() => {
fetch('http://api.example.com/api/foo').then(data => data.json()).then(parsed => setData(parsed))
}, []);in both client components that would use that same data since it would be cached. which pattern is actually recommended here?
8 Replies
Meaning that fetching from a useEffect like that on the
client will result in two duplicate calls and wasted bandwidthChampagne D’ArgentOP
@rortan thanks. so how would I properly pass the object from the server component to the client component?
where client component receives passedOb as a string, strangely enough
type Clientcomponentprops = {
passedOb: {[k: string]: Array<string>}
}async function ServerComp() {
const res = await fetch('http://www.example.com/api');
const data: Clientcomponentprops = await res.json(); // confirmed as object
return <Clientcomponent passedOb={data} />
}where client component receives passedOb as a string, strangely enough
@Champagne D’Argent <@236985086627676160> thanks. so how would I properly pass the object from the server component to the client component?
type Clientcomponentprops = {
passedOb: {[k: string]: Array<string>}
}
async function ServerComp() {
const res = await fetch('http://www.example.com/api');
const data: Clientcomponentprops = await res.json(); // confirmed as object
return <Clientcomponent passedOb={data} />
}
where client component receives passedOb as a string, strangely enough
Are you sure the API is returning an object? do a console.log on the server side just before passing it as props
This seems correct to me
I recommend zod for api response validation
Champagne D’ArgentOP
woah! I just checked this code, which I thought would have given me parsed json:
is there an issue with this code as is? I just updated the second line to
which fixed it but I feel like there's something a bit off about this. this is in a server component. thanks again for pushing me to check my assumption about what ___.json() would return
const promptData = await fetch(
process.env.NEXT_PUBLIC_SERVER_URL + "/api/get_all_prompts"
);
const allPrompts = await promptData.json();
console.log(typeof allPrompts) // prints "string"is there an issue with this code as is? I just updated the second line to
const allPrompts = JSON.parse(
await promptData.json()
);which fixed it but I feel like there's something a bit off about this. this is in a server component. thanks again for pushing me to check my assumption about what ___.json() would return