Next.js Discord

Discord Forum

React Context Error

Answered
Yellowstripe scad posted this in #help-forum
Open in Discord
Yellowstripe scadOP
Error: React Context is unavailable in Server Components

import { useSession } from "next-auth/react";
import { useRouter } from 'next/navigation'
import VoteClient from "./client";
import { getSwitch } from "./getSwitch";

export default function Page({ params }: { params: { id: string } }) {
    const { data: session, status } = useSession();
    const router = useRouter()
    if (!(status==="loading")) {
        if (!session?.user) {
            router.push("/sign-in")
        }
    }
    const foundSwitch = getSwitch({ id: params.id })
    return (
        <VoteClient foundSwitch={foundSwitch} />
    )
}


import { db } from "@/lib/db";

export async function getSwitch({ id }: { id: string }) {
    const foundSwitch = await db.preVotingSwitches.findUnique({
        where: { id: id }
    });
    return foundSwitch;
}
Answered by aardani
Make a new component like this
"use client"
export function Clientcomponent({foundSwitch}) {
    const { data: session, status } = useSession();
    return <VoteClient foundSwitch={foundSwitch} />
}
View full answer

26 Replies

delegate react hooks into a separate file that uses the "use client" directive therefore making any component declared in that file to be client component. Then import the exported client component to your Page()
client hooks is not unavailable in Server Components
this part here
@aardani this part here
Yellowstripe scadOP
app/vote/[id]/useClientHooks.tsx
"use client"

import { useSession } from "next-auth/react";
import { useRouter } from 'next/navigation';

export function useClientHooks() {
  const { data: session, status } = useSession();
  const router = useRouter();

  if (!(status === "loading")) {
    if (!session?.user) {
      router.push("/sign-in");
    }
  }

  return { session, status };
}

app/vote[id]/page.tsx
import { useSession } from "next-auth/react";
import { useRouter } from 'next/navigation'
import VoteClient from "./client";
import { useClientHooks } from "./useClientHooks";
import { getSwitch } from "./getSwitch";

export default function Page({ params }: { params: { id: string } }) {
    const { session, status } = useClientHooks();
    const foundSwitch = getSwitch({ id: params.id })
    return (
        <VoteClient foundSwitch={foundSwitch} />
    )
}


sorry, I dont think im doing this right (im new to nextjs, and javascript)

heres my error:
Error: Attempted to call useClientHooks() from the server but useClientHooks is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.
what did I do wrong
@Yellowstripe scad what did I do wrong
make a new component, not a new hook
@aardani make a new component, not a new hook
Yellowstripe scadOP
im sorry I don't understand
Make a new component like this
"use client"
export function Clientcomponent({foundSwitch}) {
    const { data: session, status } = useSession();
    return <VoteClient foundSwitch={foundSwitch} />
}
Answer
@aardani Make a new component like this js "use client" export function Clientcomponent({foundSwitch}) { const { data: session, status } = useSession(); return <VoteClient foundSwitch={foundSwitch} /> }
Yellowstripe scadOP
import ClientComponent from "./clientComponent";
import { getSwitch } from "./getSwitch";

export default function Page({ params }: { params: { id: string } }) {
    const foundSwitch = getSwitch({ id: params.id })
    return (
        <ClientComponent foundSwitch={foundSwitch} />
    )
}
import { useSession } from "next-auth/react";
import VoteClient from "./client";

"use client"
export default function ClientComponent({foundSwitch}) {
    const { data: session, status } = useSession();
    return <VoteClient foundSwitch={foundSwitch} />
}


so like this?
that looks good to me
'use client' must be at the top of the file
You can read more about it first
about client component vs server component
Yellowstripe scadOP
yeah idk its all messed up now, I have no idea what im doing sorry for wasting your time
@aardani no worries, feel free to post mroe question here
Yellowstripe scadOP
thank you so much, im going to start from scratch and try it again with all my new knowledge from today
I only started javascript around 3 days ago
@aardani no worries, feel free to post mroe question here
Yellowstripe scadOP
how do I pass in the next-auth function?
    const { data: session, status } = useSession();
    const router = useRouter()
    if (!(status === "loading")) {
        if (!session) {
            router.push("/sign-in")
        }
    }
    const Voted = hasVoted(session)


I have a type named "Session" that works, I just don't know how to pass it in

I get this error:
Argument of type 'Session | null' is not assignable to parameter of type '{ session: Session; }'.
  Type 'null' is not assignable to type '{ session: Session; }'.ts(2345)
this is how I receive it:
export default async function hasVoted({session}: {session: Session}) {
@aardani please create a new post
Yellowstripe scadOP
I realized, I did.