Reputation: 3426
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
Upvotes: 1
Views: 2199
Reputation: 1731
You can make the following changes to plug into onChange event
// pass an event handler name with different name
<PureInput
min={200}
max={price}
// pass a handler with different name as inputOptions overrides that prop
handleOnChange={handleOnChange}
type="number"
step={200}
defaultValue={element.price}
id={id}
ref={ref}
{...inputProps}
/>
//plug into the default onchange to call you handler also
<input
id={id}
ref={ref}
onChange={(e) => {
console.log("on change");
// call react-hook-form onChange
onChange(e);
// call your handler
handleOnChange(e);
}}
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}
/>
Hope it helps you in solving your problem,
Cheers
Upvotes: 1
Reputation: 3426
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
Upvotes: 1