Tech TutorBangla Web Documentation
Portfolio
HomeHTMLCSSTailwind CSSJavaScriptTypeScriptReactNext.jsNode.jsExpressSocket.IOExpoWordPressPostgreSQLPrismaPostgresNestJSMongoDBDockerTanStackTanStack TableRTK QueryGitGitHub
  • TanStack Documentation42টি অধ্যায়
প্রযুক্তি নির্বাচন
HomeHTMLCSSTailwind CSSJavaScriptTypeScriptReactNext.jsNode.jsExpressSocket.IOExpoWordPressPostgreSQLPrismaPostgresNestJSMongoDBDockerTanStackTanStack TableRTK QueryGitGitHub
  • Project Overview
  • Architecture
  • Folder Structure
  • Setup Next.js
  • Axios Setup
  • API Client
  • API Types
  • Query Install
  • Query Provider
  • Query Keys
  • Data Fetching
  • States
  • Devtools
  • Create Mutation
  • Update Mutation
  • Delete Mutation
  • Cache Invalidation
  • Optimistic Update
  • Pagination
  • Search
  • Filtering
  • Sorting
  • TanStack Table
  • Table Explore
  • Table Columns
  • Table Actions
  • React Hook Form
  • Zod Validation
  • Create Form
  • Edit Form
  • Dialog Modal
  • Delete Confirmation
  • Complete CRUD Flow
  • Full Integration
  • Error Handling
  • Loading States
  • Reusable Components
  • Production
  • Complete Project
  • Common Mistakes
  • Best Practices
  • Interview Q&A
  1. Docs
  2. TanStack
  3. Create Form — Full
TanStackIntermediate

Create Form — Full

RHF + zod + useCreateProduct মিলে CreateForm component — বাংলায়।

6টি অংশবাংলা ভাষায়
src/components/products/product-form.tsxtsx
tsx
"use client";

import { zodResolver } from "@hookform/resolvers/zod";
import { useForm, Controller } from "react-hook-form";
import { productSchema } from "@/lib/validators/product-schema";


interface ProductFormProps {
  // edit-মোড: product থাকলে defaultValues-এ বসবে
  defaultValues?: CreateProductInput;
  onSubmit: (values: CreateProductInput) => void;
  isSubmitting?: boolean;
}

export function ProductForm({
  defaultValues,
  onSubmit,
  isSubmitting,
}: ProductFormProps) {
  const form = useForm<CreateProductInput>({
    resolver: zodResolver(productSchema),
    defaultValues: defaultValues ?? {
      name: "",
      description: "",
      price: 0,
      category: "electronics",
      stock: 0,
      status: "active",
    },
  });

  return (
    <form
      onSubmit={form.handleSubmit(onSubmit)}
      className="space-y-4"
    >
      <div className="grid gap-3">
        <Label>নাম</Label>
        <Input
          placeholder="যেমন: Wireless Mouse"
          {...form.register("name")}
        />
        {form.formState.errors.name && (
          <FieldError message={form.formState.errors.name.message} />
        )}

        <Label>বিবরণ</Label>
        <Textarea
          placeholder="গুণাগুণ লিখুন…"
          {...form.register("description")}
        />
      </div>

      <div className="grid grid-cols-2 gap-3">
        <div className="space-y-1">
          <Label>দাম</Label>
          <Input
            type="number"
            step="0.01"
            {...form.register("price")}
          />
          {form.formState.errors.price && (
            <FieldError message={form.formState.errors.price.message} />
          )}
        </div>

        <div className="space-y-1">
          <Label>Stock</Label>
          <Input type="number" {...form.register("stock")} />
          {form.formState.errors.stock && (
            <FieldError message={form.formState.errors.stock.message} />
          )}
        </div>

        <div className="space-y-1">
          <Label>Category</Label>
          <Controller
            control={form.control}
            name="category"
            render={({ field }) => (
              <Select
                value={field.value}
                onValueChange={field.onChange}
              >
                <SelectTrigger>
                  <SelectValue placeholder="Category" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="electronics">Electronics</SelectItem>
                  <SelectItem value="clothing">Clothing</SelectItem>
                  <SelectItem value="books">Books</SelectItem>
                  <SelectItem value="food">Food</SelectItem>
                </SelectContent>
              </Select>
            )}
          />
        </div>

        <div className="space-y-1">
          <Label>Status</Label>
          <Controller
            control={form.control}
            name="status"
            render={({ field }) => (
              <Select
                value={field.value}
                onValueChange={field.onChange}
              >
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="active">Active</SelectItem>
                  <SelectItem value="inactive">Inactive</SelectItem>
                </SelectContent>
              </Select>
            )}
          />
        </div>
      </div>

      <Button type="submit" disabled={isSubmitting} className="w-full">
        {isSubmitting ? "সেভ হচ্ছে…" : defaultValues ? "আপডেট" : "তৈরি করুন"}
      </Button>
    </form>
  );
}

কেন Controller (Select-এ)

shadcn Select শুধু onValueChange/value বোঝে — register-এর input-event pattern মানে না। তাই Controller দিয়ে RHF-কে শুনিয়ে দিচ্ছে: value + onChange. name="category" মাধ্যমেই validation তার schema-র সাথে মিলে।

Dialog-এ ব্যবহার

Create dialogtsx
tsx
const createProduct = useCreateProduct();

<Dialog open={open} onOpenChange={setOpen}>
  <DialogContent>
    <DialogHeader>
      <DialogTitle>নতুন Product</DialogTitle>
    </DialogHeader>
    <ProductForm
      isSubmitting={createProduct.isPending}
      onSubmit={(values) => {
        createProduct.mutate(values, {
          onSuccess: () => setOpen(false),
        });
      }}
    />
  </DialogContent>
</Dialog>
ডিফল্ট ও রিসেট

defaultValues ?? {...} — create-মোডে ডিফল্ট homepage; edit-মোডে product-এর মান। Dialog বন্ধ হলে ফর্ম-মোড ব্যবহার যোগ্য থাকবে — nested component-এ form.reset() প্রায়ই নতুন dialog খোলায় লাগে।

শেষ প্যারায় নিজে practice করুন — কোড কপি করে নিজের এডিটরে চালিয়ে দেখুন।
আগেরZod Schema — ValidationপরেরEdit Form — Pre-filled
এই পেজে
Tech Tutor

বাংলায় ওয়েব ডেভেলপমেন্ট ডকুমেন্টেশন শিখুন — ধাপে ধাপে।

Homeসব ডকুমেন্টেশনQuick Startআমার নোটস

© 2026 Tech Tutor. বাংলায় শিখুন, বাংলায় গড়ুন।

mdanamolhasan1998@gmail.com