I'm trying to change the Inputs that I display based on id state variable that the user can select in a dropdown. It's odd, but after changing the select ID, the Inputs are rendered properly, but it is setting the previous Input value to the new Input.
Also, the submit is validating Input that does not exist.
import React, { useState, useEffect } from "react";
import { Controller, useForm } from "react-hook-form";
import { Button, Form, Label, Input } from "reactstrap";
const App = () => {
const [id, setID] = useState(1);
const units = [
{ UnitID: 1, UnitName: "101" },
{ UnitID: 2, UnitName: "102" },
{ UnitID: 3, UnitName: "103" },
{ UnitID: 4, UnitName: "104" }
];
useEffect(() => {
console.log("ID was updated");
}, [id]);
const {
handleSubmit,
control,
setValue,
formState: { errors }
} = useForm();
const handleChangeDeposit = (id) => {
setValue("id", parseInt(id));
setID(parseInt(id));
};
const resetFields = () => {
setValue("transactionComment", "");
setValue("unitID", 0);
};
const renderTest = () => {
switch (parseInt(id)) {
case id === 3 || id === 5:
resetFields();
return (
<div className="col-sm-3">
<Label for="transactionComment" className="mr-sm-10">
Comment
</Label>
<Controller
name="transactionComment"
control={control}
rules={{ required: true }}
defaultValue={""}
render={({ field }) => (
<Input {...field} type="text" id="transactionComment" />
)}
/>
{errors.transactionComment && (
<span style={{ color: "red" }} role="alert">
required
</span>
)}
</div>
);
case 11:
resetFields();
setValue("transactionComment", "Laundry Room");
return (
<div className="col-sm-3">
<Label for="transactionComment" className="mr-sm-10">
Comment
</Label>
<Controller
name="transactionComment"
control={control}
defaultValue={"Laundry Room"}
render={({ field }) => (
<Input
{...field}
type="text"
id="transactionComment"
readOnly
/>
)}
/>
</div>
);
default:
resetFields();
return (
<div className="col-sm-3">
<Label for="unitID" className="mr-sm-10">
Unit
</Label>
<Controller
name="unitID"
control={control}
rules={{ required: true }}
defaultValue={0}
render={({ field }) => (
<Input {...field} type="select" id="unitID">
<option value="0">Select</option>
{units.map((obj) => {
return (
<option key={obj.UnitID} value={obj.UnitID}>
{obj.UnitName}
</option>
);
})}
</Input>
)}
/>
{errors.unitID && (
<span style={{ color: "red" }} role="alert">
required
</span>
)}
</div>
);
}
};
const submitForm = (data) => {
if ([3, 5].includes(id) && data.transactionComment === "") {
alert("Transaction Comment is require");
return;
}
if (![3, 5].includes(id) && parseInt(data.unitID) === 0) {
alert("Unit is required.");
return;
}
alert("Updated!");
};
return (
<div className="row">
<div className="col-sm-12 col-md-12 col-xl-12">
<Form onSubmit={handleSubmit(submitForm)}>
<div className="row">
<div className="col-sm-3">
<Label for="id" className="mr-sm-10">
Select
</Label>
<Controller
name="id"
control={control}
rules={{ required: true }}
defaultValue={1}
render={({ field }) => (
<Input
{...field}
type="select"
id="id"
onChange={(e) => handleChangeDeposit(e.target.value)}
>
<option value="0">Select</option>
<option value="3">Option 3</option>
<option value="5">Option 5</option>
<option value="11">Option 11</option>
<option value="15">Others</option>
</Input>
)}
/>
{errors.id && (
<span style={{ color: "red" }} role="alert">
required
</span>
)}
</div>
{renderTest()}
<div className="col-sm-3">
<Label for="memo" className="mr-sm-10">
Memo
</Label>
<Controller
name="memo"
control={control}
render={({ field }) => (
<Input
{...field}
type="text"
name="memo"
placeholder="12345"
/>
)}
/>
</div>
</div>
<Button type="submit">Update</Button>
</Form>
</div>
</div>
);
};
export default App;
Here is the SandBox: https://codesandbox.io/s/serene-greider-z3xpd?file=/src/App.js:0-5426
Thanks