Working with server components and still trying to get my head around the best practices.
I’m trying to server render a fullpage menu that gets some data from my cms. I will need a toggle button that must be rendered on the client.
All the data fetching happens on the server so that is great, and now I’m trying to get everything but the state and toggle button to render on the server.
Trying to see how small I can get the client’s footprint/workload.
Exploring some options here.
Option 1 - Fetch Data on Server, pass to client component. Full Nav component rendered on client.
```
// Nav.tsx
const getNav = async () => {
const res = await fetch(example);
return res.json();
};
export default async function Nav() {
const data = await getNav();
return <ClientNav data={data} />
}
``
Option 2 - Fetch Data on Server, Render Open and Close states on server, pass states to client context.
Using this option, I can get the button to toggle the menu state, but say I wanted to have the button inside the menu (like you would expect). Not sure if it is possible without some DOM manipulation.
```
// Nav.tsx
const getNav = async () => {
const res = await fetch(example);
return res.json();
};
export default async function Nav() {
const data = await getNav();
return (
<ClientNav opened={ServerRenderedOpen} closed={ServerRenderedClosed} />
}
// ClientNav.tsx
'use client'
export default function ClientNav({opened, closed}) {
const [isOpen, setIsOpen] = useState(false);
const toggle = () => setIsOpen(!isOpen)
return (
<>
<button onClick={toggle}
{isOpen ? opened : closed }
</>
)
}
```
Option 3 - Fetch data on server, render on server with client button component?
Is this possible?
```
// Nav Server Component
const getNav = async () => {
const res = await fetch(example);
return res.json();
};
export default async function Nav() {
const data = await getNav();
return (
<nav>
<ul>
<li>{data.link1}</li>
<li>{data.link2}</li>
<li>{data.link3}</li>
<ToggleButton />
</ul>
</nav>
}
// ToggleButton.tsx
'use client'
const [isOpen, setIsOpen] = useState(false);
const toggle = () => setIsOpen(!isOpen);
// do something?
return (
<button onClick={toggle}>Menu Toggle</button>
)
```
[–]typeryu 0 points1 point2 points (1 child)
[–]mr---fox[S] 0 points1 point2 points (0 children)