i have this form using Formik, Yup and NextUi v2 Inputs and when i type in one of the imputs this warning comes out in the console
A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component.
FormContainer.jsx
import { useFormik } from "formik";
import * as Yup from "yup";
export const CheckoutContainer = () => {
const { cart, getTotalPrice, clearCart } = useContext(CartContext);
const totalPrice = getTotalPrice();
const phoneRegEx =
/^((\\+[1-9]{1,4}[ \\-]*)|(\\([0-9]{2,3}\\)[ \\-]*)|([0-9]{2,4})[ \\-]*)*?[0-9]{3,4}?[ \\-]*[0-9]{3,4}?$/;
const [orderId, setOrderId] = useState(null);
const [loaderIsVisible, setLoaderIsVisible] = useState(false);
const { handleSubmit, handleChange, errors } = useFormik({
initialValues: {
firstName: "",
lastName: "",
email: "",
address: "",
phoneNumber: "",
},
onSubmit: (data) => {
let order = {
buyer: data,
items: cart,
total: totalPrice,
};
setLoaderIsVisible(true);
clearCart();
},
validateOnChange: false,
validationSchema: Yup.object({
firstName: Yup.string()
.required("Please enter a First Name")
.min(3)
.max(15),
lastName: Yup.string()
.required("Please enter a Last Name")
.min(3)
.max(20),
email: Yup.string()
.email()
.required("Please enter a valid email address"),
address: Yup.string().required("Please enter an address").min(5),
phoneNumber: Yup.string()
.required("Please enter a valid phone number")
.matches(phoneRegEx, "Phone number is not valid"),
}),
});
return (
<>
{orderId ? (
<div className="h-screen mt-32 px-10 flex flex-col items-center space-y-5">
<h1 className="text-xl">
Your purchase has been successful. Your recipt number is:
</h1>
<span className="text-2xl font-bold">{orderId}</span>
<Link
to="/"
className="md:w-[50%] w-full h-10 bg-blue-600 rounded-lg text-white hover:bg-blue-500 flex justify-center items-center"
>
Continue shopping
</Link>
</div>
) : (
<Checkout
totalPrice={totalPrice}
handleSubmit={handleSubmit}
handleChange={handleChange}
errors={errors}
loaderIsVisible={loaderIsVisible}
/>
)}
</>
);
};
Checkout.jsx
import { Input, Spinner } from "@nextui-org/react";
export const Checkout = ({
totalPrice,
handleSubmit,
handleChange,
loaderIsVisible,
errors,
}) => {
return (
<div className="h-screen mt-28 flex flex-col">
<div className="flex flex-col md:flex-row md:justify-between w-full border-b pb-2 sticky top-20 z-[8] px-10 py-2 bg-white/30 backdrop-blur-sm">
<h1 className="text-2xl font-medium">Checkout</h1>
<span className="text-blue-500 md:self-end">
Order summary: {totalPrice} USD
</span>
</div>
<span className="py-10 font-semibold text-4xl px-10">
Now fill out your information.
</span>
{/* FORM */}
<form className="flex flex-col md:w-[50%] space-y-10 z-0 px-10">
<Input
label="First Name"
variant="bordered"
name="firstName"
color="primary"
errorMessage={errors.firstName}
onChange={handleChange}
/>
<Input
label="Last Name"
name="lastName"
variant="bordered"
color="primary"
errorMessage={errors.lastName}
onChange={handleChange}
/>
<Input
bordered
label="Email"
variant="bordered"
name="email"
type="email"
color="primary"
errorMessage={errors.email}
onChange={handleChange}
/>
<Input
label="Street Address"
variant="bordered"
name="address"
color="primary"
errorMessage={errors.address}
onChange={handleChange}
/>
<Input
label="Phone Number"
variant="bordered"
name="phoneNumber"
color="primary"
errorMessage={errors.phoneNumber}
onChange={handleChange}
/>
</form>
<button
type="submit"
onClick={handleSubmit}
className="h-10 bg-blue-600 rounded-lg text-white hover:bg-blue-500 md:w-[44%] my-10 mx-10"
>
<span className=""> Buy</span>
{loaderIsVisible && <Spinner className="float-right mr-5 mt-1" />}
</button>
</div>
);
};
I fixed it adding ({values}) to useFormik() and passing as a prop to Checkout