I have a checkout cart where you have different cart items, and for each one you can change the quantity prior to purchase.
Here's how the code looks:
import React, { useEffect, useState } from "react";
import PureInput from "./PureInput";
import { useForm, Controller } from "react-hook-form";
const CartInner = React.forwardRef(
(
{
control,
element,
value,
handleOnChange,
images,
name,
monthlyAmount,
price,
projectedGrowth,
id,
...inputProps
}: any,
ref: any
) => {
return (
<div className="grid gap-8 grid-cols-2 mb-12 py-6 px-8 border-2 border-slate-200">
<div>
<PureInput
min={200}
max={price}
onChange={handleOnChange}
type="number"
step={200}
defaultValue={element.price}
id={id}
ref={ref}
{...inputProps}
/>
</div>
</div>
);
}
);
export default function Checkout() {
const { control, handleSubmit } = useForm();
const handleOnChange = (index: any, e: any) => {
console.log(e, "e");
};
const onSubmit = async (data: any) => {
console.log(data, "data from Form.tsx");
};
return (
<form onSubmit={handleSubmit(onSubmit)} className="grid gap-8 grid-cols-3">
<div className="col-span-2">
{[0, 2].map((element, index) => {
return (
<fieldset key={index}>
<Controller
render={({ field }) => (
<CartInner
element={element}
handleOnChange={(e) => handleOnChange(index, e)}
{...field}
/>
)}
name={`test.${index}.lastName`}
control={control}
/>
</fieldset>
);
})}
<button>Progess to payment</button>
</div>
</form>
);
}
And the PureInput:
import * as React from "react";
type IProps = any;
const PureInput = React.forwardRef(
({ className, id, onChange, ...inputProps }: IProps, ref: any) => {
return (
<input
id={id}
ref={ref}
onChange={onChange}
type="input"
className={`${className} block w-full bg-white text-black rounded-md border-2 font-bold border-grey-200 text-xl px-4 py-4 focus:border-orange-500 focus:ring-orange-500`}
{...inputProps}
/>
);
}
);
export default PureInput;
Everything works fine in terms of submitting the form. When I do, I get an array of whatever values I have entered into the input:
[{lastName: "1600"}
{lastName: "800"}]
My package versions:
"react-dom": "18.2.0",
"react-hook-form": "^7.29.0",
But my onChange no longer fires. How can I get the onChange to fire so I can log the value of the input inside <Checkout />
component?
Here's a codesandbox if it helps
CodePudding user response:
The onChange
event handler is only called when the input value is changed. It's not called when the form is submitted.
To access the values of the inputs when the form is submitted, you can use the handleSubmit
hook provided by react-hook-form
in your Checkout
component. This hook takes a callback function as an argument, and this function will be called when the form is submitted. The values of the form inputs will be passed to this callback as an object:
import React, { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
const CartInner = React.forwardRef(
(
{
control,
element,
value,
handleOnChange,
images,
name,
monthlyAmount,
price,
projectedGrowth,
id,
...inputProps
}: any,
ref: any
) => {
return (
<div className="grid gap-8 grid-cols-2 mb-12 py-6 px-8 border-2 border-slate-200">
<div>
<PureInput
min={200}
max={price}
onChange={handleOnChange}
type="number"
step={200}
defaultValue={element.price}
id={id}
ref={ref}
{...inputProps}
/>
</div>
</div>
);
}
);
export default function Checkout() {
const { control, handleSubmit } = useForm();
const handleOnChange = (index: any, e: any) => {
console.log(e, "e");
};
const onSubmit = async (data: any) => {
console.log(data, "data from Form.tsx");
};
return (
<form onSubmit={handleSubmit(onSubmit)} className="grid gap-8 grid-cols-3">
<div className="col-span-2">
{[0, 2].map((element, index) => {
return (
<fieldset key={index}>
<Controller
render={({ field }) => (
<CartInner
element={element}
handleOnChange={(e) => handleOnChange(index, e)}
{...field}
/>
)}
name={`test.${index}.lastName`}
control={control}
/>
</fieldset>
);
})}
<button>Progess to payment</button>
</div>
</form>
);
}
CodePudding user response:
This part of the documentation led me to the answer:
import React, { useEffect, useState } from "react";
import PureInput from "./PureInput";
import { useForm, Controller } from "react-hook-form";
const CartInner = React.forwardRef(
({ onChange, onBlur, name, label, ...inputProps }: any, ref: any) => {
return (
<input
name={name}
ref={ref}
onChange={onChange}
onBlur={onBlur}
type="number"
/>
);
}
);
export default function Checkout() {
const { control, handleSubmit } = useForm();
const handleOnChange = (index: any, e: any) => {
console.log(e.target.value, "e");
};
const onSubmit = async (data: any) => {
console.log(data, "data from Form.tsx");
};
return (
<form onSubmit={handleSubmit(onSubmit)} className="grid gap-8 grid-cols-3">
<div className="col-span-2">
{[0, 2].map((element, index) => {
return (
<fieldset key={index}>
<Controller
render={({ field: { onBlur, value, name, ref } }) => (
<CartInner
key={index}
name={name}
ref={ref}
onChange={(e) => handleOnChange(index, e)}
onBlur={onBlur}
/>
)}
name={`test.${index}.lastName`}
control={control}
/>
</fieldset>
);
})}
<button>Progess to payment</button>
</div>
</form>
);
}
// add delete
// total money
// add the cart documents to a history with a timestamp and show it was a BUY ORDER
// delete the documents from the cart