Created
June 28, 2024 12:35
-
-
Save Joeldorne/ab1419c4c4d35bc9e794b81ade0e7a62 to your computer and use it in GitHub Desktop.
Client Side Component - TanStack Form
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| "use client" | |
| import { useForm } from "@tanstack/react-form" | |
| import { zodValidator } from "@tanstack/zod-form-adapter" | |
| import { z } from "zod" | |
| import { submitForm } from "./actions" // Make sure to create this file with the server action | |
| import { useState } from "react" | |
| const formSchema = z.object({ | |
| name: z.string().min(2, "Name must be at least 2 characters"), | |
| email: z.string().email("Invalid email address"), | |
| }) | |
| type FormValues = z.infer<typeof formSchema> | |
| export default function MyForm() { | |
| const [serverResponse, setServerResponse] = useState<{ error?: string; success?: boolean; message?: string }>({}) | |
| const form = useForm<FormValues>({ | |
| defaultValues: { | |
| name: "", | |
| email: "", | |
| }, | |
| onSubmit: async (values) => { | |
| try { | |
| const result = await submitForm(values) | |
| setServerResponse(result) | |
| } catch (error) { | |
| setServerResponse({ error: error.message }) | |
| } | |
| }, | |
| validatorAdapter: zodValidator, | |
| }) | |
| return ( | |
| <form.Provider> | |
| <form | |
| onSubmit={(e) => { | |
| e.preventDefault() | |
| e.stopPropagation() | |
| form.handleSubmit() | |
| }} | |
| className="space-y-4" | |
| > | |
| <div> | |
| <label htmlFor="name" className="block text-sm font-medium text-gray-700">Name:</label> | |
| <form.Field | |
| name="name" | |
| validators={{ onChange: formSchema.shape.name }} | |
| > | |
| {(field) => ( | |
| <div> | |
| <input | |
| id="name" | |
| name={field.name} | |
| value={field.state.value} | |
| onBlur={field.handleBlur} | |
| onChange={(e) => field.handleChange(e.target.value)} | |
| className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" | |
| /> | |
| {field.state.meta.touchedErrors ? ( | |
| <em className="text-red-500 text-sm">{field.state.meta.touchedErrors}</em> | |
| ) : null} | |
| </div> | |
| )} | |
| </form.Field> | |
| </div> | |
| <div> | |
| <label htmlFor="email" className="block text-sm font-medium text-gray-700">Email:</label> | |
| <form.Field | |
| name="email" | |
| validators={{ onChange: formSchema.shape.email }} | |
| > | |
| {(field) => ( | |
| <div> | |
| <input | |
| id="email" | |
| name={field.name} | |
| value={field.state.value} | |
| onBlur={field.handleBlur} | |
| onChange={(e) => field.handleChange(e.target.value)} | |
| className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" | |
| /> | |
| {field.state.meta.touchedErrors ? ( | |
| <em className="text-red-500 text-sm">{field.state.meta.touchedErrors}</em> | |
| ) : null} | |
| </div> | |
| )} | |
| </form.Field> | |
| </div> | |
| <button | |
| type="submit" | |
| className="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" | |
| > | |
| Submit | |
| </button> | |
| {serverResponse.error && ( | |
| <p className="mt-2 text-sm text-red-600">Error: {serverResponse.error}</p> | |
| )} | |
| {serverResponse.success && ( | |
| <p className="mt-2 text-sm text-green-600">{serverResponse.message}</p> | |
| )} | |
| </form> | |
| </form.Provider> | |
| ) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment