Reputation: 639
I have the following form:
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="voucherPrice"
control={control}
defaultValue={false}
rules={{ required: true }}
render={({ field: { onChange, value, ref } }) => (
<Input {...field} onChange={(ev) => handlePriceInputChange(ev)} value={price} type="number" innerRef={ref} />
)}
/>
<p>{errors.voucherPrice?.message}</p>
<Button
variant="contained"
sx={{ mt: 1, mr: 1 }}
type="submit"
>
{"Continue"}
</Button>
</form>
and with this configuration:
function PriceSelection(props) {
const {
register,
handleSubmit,
control,
formState: { errors },
} = useForm({
resolver: yupResolver(schema),
});
const onSubmit = (data) => {
console.log("does not work?", data);
};
const classes = useStylesPriceSelection();
const [selected, setSelected] = useState(false);
const [price, setPrice] = useState("");
const handlePriceInputChange = (ev) => {
console.log("change", price);
setPrice(parseInt(ev.target.value));
};
The function onSubmit
does not trigger when I press the submit button. Also I would like the input field to be filled by default by the state price
and its value to be sent with the parameter data
on the function onSubmit
when I push the submit button.
Upvotes: 2
Views: 5365
Reputation: 6989
You are mixing useState
with react-hook-form
and are not updating react-hook-form
's internal form state. You don't need to declare a useState
for your field.
In your example you are destructering onChange
from the field
object of <Controller />
but you are never using it for your <Input />
component. Therefore react-hook-form
can't update it's form state. As you set your field to be required the onSubmit
callback won't get triggered because react-hook-form
will never receive an update or value for it.
The correct way would be:
<Controller
name="voucherPrice"
control={control}
rules={{ required: true }}
render={({ field: { ref, onChange, value, ...field } }) => (
<Input {...field} onChange={onChange} value={value} type="number" innerRef={ref} />
)}
/>
Or even shorter:
<Controller
name="voucherPrice"
control={control}
rules={{ required: true }}
render={({ field: { ref, ...field } }) => (
<Input {...field} type="number" innerRef={ref} />
)}
/>
UPDATE
If you need to have access to the value outside of the <Controller />
, you should use react-hook-form
's watch
method. This will allow you to subscribe to the latest value of the voucherPrice
field and use it inside your component -> Docs
If you want to set or update the value programmatically you can use the setValue
method from react-hook-form
-> Docs
const { control, handleSubmit, watch, setValue } = useForm();
const voucherPrice = watch("voucherPrice");
const onButtonClick = () => {
setValue("voucherPrice", <newValue>);
}
If you really need to have a separate useState
for your value and want to update it additionally to your react-hook-form
field update, you could do the following:
<Controller
name="voucherPrice"
control={control}
rules={{ required: true }}
render={({ field: { ref, onChange, value, ...field } }) => (
<Input
{...field}
onChange={(v) => {
onChange(v);
handlePriceInputChange(v);
}}
value={value}
type="number"
innerRef={ref}
/>
)}
/>
But i would suggest to use the react-hook-form
only solution, as it has all the functionality you need to manage your form state.
Upvotes: 3