Next.js Discord

Discord Forum

Several issues with simple server component

Answered
Masai Lion posted this in #help-forum
Open in Discord
Masai LionOP
I'm trying to get a pretty simple server component working in a <Suspense>. It shows in a modal, like this:

"use client"

function SessionModal({session}: SessionModalProps) {
    return <Suspense fallback={<LoadingPage />}>
        <SessionPage sessionId={session.sessionId} />
    </Suspense>
}


"use server"

export interface SessionPageProps {
    sessionId: string
}

export async function SessionPage({sessionId}: SessionPageProps) {
    console.log("rendered!")
    const sessionStuff = await someFetch(sessionId)
    return <div>some content based on the session data</div>
}


In my testing, it pretty much works exactly as I would expect. There is no visible bug. However, I'm getting errors in both the server and client, and for some reason my server component is rendered 5 times.

On server (this one only happens the first time the server component is mounted during a browser session):
⨯ TypeError: Cannot destructure property 'sessionId' of 'props' as it is undefined.
...
rendered!
rendered!
rendered!
rendered!
rendered!

Note: The client renders twice, because the modal is attached inside useEffect and strict mode causes it to mount/unmount/remount.

On client:
app-index.js:34 Warning: Cannot update a component (`Router`) while rendering a different component (`proxy`). To locate the bad setState() call inside `proxy`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render
    at proxy
    at Suspense
    at div
    at SessionModal (webpack-internal:///(app-pages-browser)/./src/components/admin/admin.page.tsx:145:11)
    at div
    ...


Am I doing something totally wrong?
Answered by Ray
please read the doc
View full answer

8 Replies

@Masai Lion I'm trying to get a pretty simple server component working in a `<Suspense>`. It shows in a modal, like this: typescript "use client" function SessionModal({session}: SessionModalProps) { return <Suspense fallback={<LoadingPage />}> <SessionPage sessionId={session.sessionId} /> </Suspense> } typescript "use server" export interface SessionPageProps { sessionId: string } export async function SessionPage({sessionId}: SessionPageProps) { console.log("rendered!") const sessionStuff = await someFetch(sessionId) return <div>some content based on the session data</div> } In my testing, it pretty much works exactly as I would expect. There is no visible bug. *However*, I'm getting errors in both the server and client, and for some reason my server component is rendered 5 times. On server (this one only happens the first time the server component is mounted during a browser session): ⨯ TypeError: Cannot destructure property 'sessionId' of 'props' as it is undefined. ... rendered! rendered! rendered! rendered! rendered! Note: The client renders twice, because the modal is attached inside `useEffect` and strict mode causes it to mount/unmount/remount. On client: app-index.js:34 Warning: Cannot update a component (`Router`) while rendering a different component (`proxy`). To locate the bad setState() call inside `proxy`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render at proxy at Suspense at div at SessionModal (webpack-internal:///(app-pages-browser)/./src/components/admin/admin.page.tsx:145:11) at div ... Am I doing something totally wrong?
You are rendering SessionPage in a client component so it will be a client component too which mean you can't do await someFetch in it
"use server" is for server action, it doesn't make the component from client component to server component
@Ray You are rendering `SessionPage` in a client component so it will be a client component too which mean you can't do `await someFetch` in it
Masai LionOP
that doesn't seem true based on the actual behavior.
* rendered! is only logged on the server, not the client
* the fetch works as expected; like I said, this works fine as far as I can tell. it shows the loading ui for a moment and then renders the content I'm expecting, which only the server can retrieve
if this is an unsupported use (which maybe it is, I don't actually see it in the docs), it's weird that other than the weird errors it works exactly as I expect it to
yes, Im not sure how you make it work from the code you provided
please read the doc
Answer
Masai LionOP
got it, I guess I'll file an issue that this should warn the user, instead of mostly working