Reputation: 353
How to pass data from the server component to the client component in Next.js 13 app router?
I am calling an external API in page.tsx which gives the city of the person. I want to pass this city to the client component where this city can be displayed and changed. What will be the best way to achieve this? In React we can use redux but since this is next.js 13 server component not sure how to do it.
app/page.tsx
const Page = async () => {
const city = await getCity();
const hotels = await getHotelsByCity({
city: city,
});
return (
<div className="pt-24 md:pt-28 flex md:flex-row md:flex-wrap flex-col">
{hotels &&
hotels.map((hotel) => {
<div>{hotel}</div>;
})}
</div>
);
};
export default Page;
app/components/Navbar/Location.tsx
"use client";
import useSelectLocationModal from "@/app/hooks/useSelectLocationModal";
export default function Location() {
const selectLocationModal = useSelectLocationModal();
return (
<div
className="flex items-center cursor-pointer"
onClick={() => selectLocationModal.onOpen()}
>
<p>{city}</p>
</div>
);
}
Upvotes: 25
Views: 20659
Reputation: 3931
It's not currently possible with hooks. There used to be an experimental hook named useActionState
that returned functions equivalent to [state, setState]
, where state
and setState
could be passed to child client components as props, but it did not work properly and has been removed from the documentation. Hopefully the Next.js team finds a way to fix it, because it's essential functionality for a full stack framework.
For now, I believe that you'll need to set up a Route Handler and then call it from the frontend with fetch()
, as you would with a separate frontend and backend.
Upvotes: 2
Reputation: 14846
You can pass the data as props, you just need to make sure that it is serialized .
for instance
export default async function Home() {
let data;
console.log("fetching data");
try{
const res = await fetch(process.env.API_URL + '/endpoint', {
headers: {
'Accept': 'application/json'
},
next: {
tags: ['homepage']
}
});
data = await res.json();
}
catch (e) {
console.log(e);
}
return (
<main>
<YourClientComponent data={data}/>
</main>
)
}
Upvotes: 16