I am developing a simple form to send messages to my email with the help of EmailJS
. The EmailJS
settings look fine, I tested them through the website and I got a 200
response.
This is my code:
"use client";
import { Button } from "./ui/button";
import { Input } from "./ui/input";
import { Textarea } from "./ui/textarea";
import { User, MailIcon, ArrowRightIcon, MessageSquare } from "lucide-react";
import emailjs from "@emailjs/browser";
import { ChangeEvent, FormEvent, useRef, useState } from "react";
const Form = () => {
const formRef = useRef<HTMLFormElement>(null);
const [form, setForm] = useState({
name: "",
email: "",
message: "",
});
const handleChange = (
e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
const { name, value } = e.target;
setForm({ ...form, [name]: value });
};
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
console.log("Dati del form:", form); // Verifica i dati del form nel log
emailjs
.send(
"service_+++++",
"template_++++++",
{
from_name: form.name,
to_name: "Jhon Doe",
from_email: form.email,
to_email: "[email protected]",
message: form.message,
},
"WYI3ob++++++++"
)
.then(
() => {
alert("Thank you for your message!");
setForm({
name: "",
email: "",
message: "",
});
},
(error: Error) => {
console.log(error);
alert("Something went wrong");
}
);
};
return (
<form
ref={formRef}
onSubmit={handleSubmit}
className="flex flex-col gap-y-4"
>
<div className="relative flex items-center">
<Input
onChange={handleChange}
type="text"
id="name"
placeholder="Name"
required
value={form.name}
/>
<User className="absolute right-6" size={20} />
</div>
<div className="relative flex items-center">
<Input
onChange={handleChange}
type="email"
id="email"
placeholder="Email"
required
value={form.email}
/>
<MailIcon className="absolute right-6" size={20} />
</div>
<div className="relative flex items-center">
<Textarea
onChange={handleChange}
required
placeholder="Type your message"
value={form.message}
/>
<MessageSquare className="absolute top-4 right-6" size={20} />
</div>
<Button className="flex items-center gap-x-1 max-w-[166px] rounded-[80px]">
Let' s Talk
<ArrowRightIcon size={20} />
</Button>
</form>
);
};
export default Form;
Right now I am not able to type anything in the input
or even copy, it is like they are stuck to the initial state of empty strings.
I am also using shadcn
, in fact, the Input
and TextArea
components come from there. Anyone knows why I am facing this problem?
I also tried to use normal input
and text area
but I still can't type into any of the inputs.
I also tried to use defaultValues
and in that case I can type into the inputs but the object with name
, email
, and message
remain an empty string.
The issue you're experiencing is likely due to the way you're handling the id
attribute in your <Input />
and <Textarea />
components and not correctly associating the name
attribute with your form's state.
For the useState
hook to correctly update the state based on input changes, you need to ensure that the name
attribute of each input matches the keys in your state object.
In your code, you're setting the id
attribute for <Input />
and <Textarea />
, but you're not setting their name
attribute, which is essential for the handleChange
function to update the state correctly based on which input is changed.
The handleChange
function uses the name
attribute to determine which part of the state to update.
Below is the updated return ()
function based off of your shared code:
return (
<form
ref={formRef}
onSubmit={handleSubmit}
className="flex flex-col gap-y-4"
>
<div className="relative flex items-center">
<Input
name="name" // Add the name attribute
onChange={handleChange}
type="text"
id="name"
placeholder="Name"
required
value={form.name}
/>
<User className="absolute right-6" size={20} />
</div>
<div className="relative flex items-center">
<Input
name="email" // Add the name attribute
onChange={handleChange}
type="email"
id="email"
placeholder="Email"
required
value={form.email}
/>
<MailIcon className="absolute right-6" size={20} />
</div>
<div className="relative flex items-center">
<Textarea
name="message" // Add the name attribute
onChange={handleChange}
required
placeholder="Type your message"
value={form.message}
/>
<MessageSquare className="absolute top-4 right-6" size={20} />
</div>
<Button className="flex items-center gap-x-1 max-w-[166px] rounded-[80px]">
Let' s Talk
<ArrowRightIcon size={20} />
</Button>
</form>
);