Error: createContext only works in Client Components (Want to move it to server components)
Answered
Silver Marten posted this in #help-forum
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
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.
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:
component.client.tsx:
import ClientComponent from './component.client.tsx'
export default function ServerComponent() {
return (
<ClientComponent />
)
}component.client.tsx:
'use client'
export default function ClientComponent() {
return (
<ThingsWithContext />
)
}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:
component.client.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)
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)
@ncls. component.server.tsx:
TS
import ClientComponent from './component.client.tsx'
export default function ServerComponent() {
return (
<ClientComponent />
)
}
component.client.tsx:
TS
'use client'
export default function ClientComponent() {
return (
<ThingsWithContext />
)
}
Silver MartenOP
this helped btw thank you
@Silver Marten 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)
European sprat
You can also use something like react query to help with the prop drilling