Next.js Discord

Discord Forum

Error: createContext only works in Client Components (Want to move it to server components)

Answered
Silver Marten posted this in #help-forum
Open in Discord
Silver MartenOP
So to break it down it down I have a form component that I want to move from a client component to a server component.

However every time I remove the "use client" at the top I am getting this error.

For more context this is my code

"use client" // This is the use client I want to remove


// Import necessary modules and components
import ChannelInput from '@/components/custom/form/FormInput/ChannelInput';
import ProjectNameInput from '@/components/custom/form/FormInput/ProjectNameInput';
import ChainInput from '@/components/custom/form/FormInput/ChainInput';
import TelegramLinkInput from '@/components/custom/form/FormInput/TelegramLinkInput';
import WebsiteLinkInput from '@/components/custom/form/FormInput/WebsiteLinkInput';
import ImageLinkInput from '@/components/custom/form/FormInput/ImageLinkInput';
import ContractAddressInput from '@/components/custom/form/FormInput/ContractAddressInput';
import PinnedPostInput from '@/components/custom/form/FormInput/PinnedPostInput';
import {
  Form,
} from "@/components/ui/form";
import DescriptionInput from "./FormInput/DescriptionInput";
import { SubmitButton, onSubmit } from "./FormInput/FormSubmit";
import { useMainForm } from "@/hooks/useMainForm";



export function MainForm() {
  // Use the useForm hook with the FormSchema for form validation
  const form = useMainForm();

  // Render the form using the Form and related components
  return (
    <Form {...form}>
      <form
        onSubmit={form.handleSubmit(onSubmit)}
        className="grid grid-cols-2 gap-3 space-y-1"
      >
        {/* Channel Input */}
        <div className="col-span-2">
          <ChannelInput />
        </div>

        {/* Project Name Input */}
        <div>
          <ProjectNameInput />
        </div>

        {/* Chain Input */}
        <div>
          <ChainInput />
        </div>

        {/* Description Input */}
        <div className="col-span-2">
          <DescriptionInput />
        </div>

        {/* Telegram Link Input */}
        <div>
         <TelegramLinkInput />
        </div>

        {/* Website Link Input */}
        <div>
         <WebsiteLinkInput />
        </div>

        {/* Contract Address Link Input */}
        <div className="col-span-2">
         <ContractAddressInput />
        </div>

        {/* Image Link Input */}
        <div className="col-span-2">
          <ImageLinkInput />
        </div>

        {/* Pinned Post Input */}
        <div className="col-span-2">
          <PinnedPostInput />
        </div>

        <div className="col-span-2 flex justify-center">
          {/* Submit button */}
          <SubmitButton />
        </div>
      </form>
    </Form>
  );
}



and for context this is one of the inputs, they all have the similar style, I have tried to add "use client" to all of the inputs but it still didn't work. Would really like some more help on this.

import { FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage } from "@/components/ui/form";
import { Textarea } from "@/components/ui/textarea"
import { useFormContext } from "react-hook-form";



export default function DescriptionInput() {


 const { control } = useFormContext();
    return (
            <FormField
              control={control}
              name="description"
              render={({ field }) => (
                <FormItem>
                <FormLabel>Description</FormLabel>
                <FormControl>
                  <Textarea
                    placeholder="Tell us a little bit about your project."
                    className="resize-none"
                    {...field}
                  />
                </FormControl>
                <FormDescription>
                  Type a message you want displayed on the group.
                </FormDescription>
                <FormMessage />
              </FormItem>
              )}
            />
          );
}
Answered by ncls.
component.server.tsx:
import ClientComponent from './component.client.tsx'

export default function ServerComponent() {
  return (
    <ClientComponent />
  )
}

component.client.tsx:
'use client'

export default function ClientComponent() {
  return (
    <ThingsWithContext />
  )
}
View full answer

8 Replies

European sprat
You can't use context, hooks, etc in server components
Silver MartenOP
dammit, any way to get what I want, I am trying to turn the first bit of code into a server component to do an async await
@Silver Marten dammit, any way to get what I want, I am trying to turn the first bit of code into a server component to do an async await
You could make a child component that uses the useContext part and include it in your server component
Silver MartenOP
uhhhh can you explain more, because I think I tried that and got the same problem, im just having a hard time comprehending where the useContext is because it's in a child component anyways
@Silver Marten uhhhh can you explain more, because I think I tried that and got the same problem, im just having a hard time comprehending where the useContext is because it's in a child component anyways
component.server.tsx:
import ClientComponent from './component.client.tsx'

export default function ServerComponent() {
  return (
    <ClientComponent />
  )
}

component.client.tsx:
'use client'

export default function ClientComponent() {
  return (
    <ThingsWithContext />
  )
}
Answer
Silver MartenOP
okay now hypothetically, if I want to now fetch data from the ServerComponent using the async await ..

Will I then need to prop drill (idk if that is the correct terminology) to pass the props down from the data I get into one of the components (Thing with context)