I am using Ant Design 4 to make a dynamic form like this: there is an "Add form item" button, when you click it, you can add a select box to your form. After selecting one option from that select box, there will be some inputs with an initial value based on the selected value data. My problem is these inputs fields only render one time when selecting one value from the select box for the first time. I have logged the "item" data inside infoData[0]?.map((item, index), it returns with the right value but the Form Inputs do not update their initialValue. Here is my code:
import React, { useState, useCallback } from "react";
import { Button, Form, Select, Input } from "antd";
const FormPage = () => {
const [userData, setUserData] = useState([]);
const [optionList, setOptionList] = useState([
{
name: "Option 1",
value: "o-1",
info: [
{ name: "Option 1 Info 1", point: 11 },
{ name: "Option 1 Info 2", point: 12 },
],
},
{
name: "Option 2",
value: "o-2",
info: [
{ name: "Option 2 Info 1", point: 13 },
{ name: "Option 2 Info 2", point: 14 },
],
},
]);
const onSubmitForm = (values: object) => {
console.log(values);
};
const addUserData = () => {
const newData = {
id: Math.random().toString(36).substring(7),
userName: Math.random().toString(36).substring(7),
};
setUserData([...userData, newData]);
};
const selectedOption = (val) => {
const selectedData = optionList.filter((item) => item.value === val);
return selectedData[0].info;
};
return (
<Form onFinish={onSubmitForm}>
<p>
<Button onClick={addUserData}>Add Form Item</Button>
</p>
{userData.length > 0
? userData.map((item, index) => (
<FormPageItem
key={index}
data={item}
index={index}
addUserData={addUserData}
optionList={optionList}
selectedOption={selectedOption}
/>
))
: ""}
<Button type="primary">Submit</Button>
</Form>
);
};
const FormPageItem = (props) => {
const [infoData, setInfoData] = useState([]);
const handleSelectOption = (value) => {
const selected = props.selectedOption(value);
console.log("selected", selected);
const newData = [...infoData];
newData[0] = selected;
console.log(newData);
setInfoData(newData);
};
const renderInput = useCallback(() => {
if (infoData.length > 0) {
return (
<>
{infoData[0]?.map((item, index) => (
<Form.Item
name={[`option-${props.data.id}`, `user-info-${index}`]}
style={{ marginBottom: 16 }}
initialValue={item.name}
key={index}
>
<Input />
</Form.Item>
))}
</>
);
}
return "";
}, [infoData]);
return (
<div>
<Form.Item
name={[`option-${props.data.id}`, "options"]}
label="Option List"
>
<Select showArrow={false} onChange={handleSelectOption}>
{props.optionList.map((item) => (
<Select.Option value={item.value} key={item.value}>
{item.name}
</Select.Option>
))}
</Select>
{renderInput()}
</Form.Item>
</div>
);
};
export default FormPage;