I'm having an Ant Design <Form>
ponent with <Form.Items>
which have onChange events. If the onChange event function is true I'm displaying extra content.
So in the example sandbox I created, when changing all the the <Radio>
to Yes it fires the onChange event which is validated and then showing a div with the text "You checked all answered with yes".
As I'm using <Form>
it is a form controlled environment so I'm using form
to set and reset values. But when calling form.resetFields()
the onChange handlers are not called. So the message won't go away as the state not refreshes. So I have to find a way to call a function from the parent ponent which refreshes the form values in the child ponent.
Using useImperativeHandle()
for every field to update on more plex forms to call functions from the parent seems way too plex for such a simple task. And adding custom events to municate with parent ponents seem to be a not very react way when reading this stack overflow thread
Is there something from the Ant Design form I'm missing? Because this must be a mon task. What's a good way to approach this problem?
Link to code sandbox with an example:
=/src/AntDFormChild.js
Example
const formLayout = {
labelCol: { span: 8 },
wrapperCol: { span: 7 }
};
const questionDefaultValues = {
rjr01_q01: 2,
rjr02_q01: 2
};
const AntDForm = () => {
const [form] = Form.useForm();
const handleResetForm = () => {
form.resetFields();
// now force onChange of child ponent to update
};
const handleFillForm = () => {
form.setFieldsValue({ rjr01_q01: 1, rjr02_q01: 1 });
// now force onChange of child ponent to update
};
return (
<>
<Button onClick={handleResetForm}>Reset Form</Button>
<Button onClick={handleFillForm}>Fill Form</Button>
<Form
{...formLayout}
form={form}
initialValues={{ ...questionDefaultValues }}
>
<AntDFormChild form={form} />
</Form>
</>
);
};
const questionQualifiedValues = {
rjr01_q01: 1,
rjr02_q01: 1
};
const AntDFormChild = ({ form }) => {
const [isQualified, setIsQualified] = useState(false);
const [questionFormValues, setQuestionFormValues] = useState({});
useEffect(() => {
if (shallowEqual(questionFormValues, questionQualifiedValues)) {
setIsQualified(true);
} else {
setIsQualified(false);
}
}, [questionFormValues]);
function shallowEqual(object1, object2) {
const keys1 = Object.keys(object1);
const keys2 = Object.keys(object2);
if (keys1.length !== keys2.length) {
return false;
}
for (let key of keys1) {
if (object1[key] !== object2[key]) {
return false;
}
}
return true;
}
return (
<>
{isQualified && (
<div style={{ color: "red" }}>You checked all answered with yes</div>
)}
<Form.Item name="rjr01_q01" label="Question 1">
<Radio.Group
onChange={(i) => {
setQuestionFormValues((questionFormValues) => ({
...questionFormValues,
rjr01_q01: i.target.value
}));
}}
>
<Radio value={1}>Yes</Radio>
<Radio value={0}>No</Radio>
<Radio value={2}>Unknown</Radio>
</Radio.Group>
</Form.Item>
<Form.Item name="rjr02_q01" label="Question 2">
<Radio.Group
onChange={(i) => {
setQuestionFormValues((questionFormValues) => ({
...questionFormValues,
rjr02_q01: i.target.value
}));
}}
>
<Radio value={1}>Yes</Radio>
<Radio value={0}>No</Radio>
<Radio value={2}>Unknown</Radio>
</Radio.Group>
</Form.Item>
</>
);
};
I'm having an Ant Design <Form>
ponent with <Form.Items>
which have onChange events. If the onChange event function is true I'm displaying extra content.
So in the example sandbox I created, when changing all the the <Radio>
to Yes it fires the onChange event which is validated and then showing a div with the text "You checked all answered with yes".
As I'm using <Form>
it is a form controlled environment so I'm using form
to set and reset values. But when calling form.resetFields()
the onChange handlers are not called. So the message won't go away as the state not refreshes. So I have to find a way to call a function from the parent ponent which refreshes the form values in the child ponent.
Using useImperativeHandle()
for every field to update on more plex forms to call functions from the parent seems way too plex for such a simple task. And adding custom events to municate with parent ponents seem to be a not very react way when reading this stack overflow thread
Is there something from the Ant Design form I'm missing? Because this must be a mon task. What's a good way to approach this problem?
Link to code sandbox with an example:
https://codesandbox.io/s/vigilant-curran-dqvlc?file=/src/AntDFormChild.js
Example
const formLayout = {
labelCol: { span: 8 },
wrapperCol: { span: 7 }
};
const questionDefaultValues = {
rjr01_q01: 2,
rjr02_q01: 2
};
const AntDForm = () => {
const [form] = Form.useForm();
const handleResetForm = () => {
form.resetFields();
// now force onChange of child ponent to update
};
const handleFillForm = () => {
form.setFieldsValue({ rjr01_q01: 1, rjr02_q01: 1 });
// now force onChange of child ponent to update
};
return (
<>
<Button onClick={handleResetForm}>Reset Form</Button>
<Button onClick={handleFillForm}>Fill Form</Button>
<Form
{...formLayout}
form={form}
initialValues={{ ...questionDefaultValues }}
>
<AntDFormChild form={form} />
</Form>
</>
);
};
const questionQualifiedValues = {
rjr01_q01: 1,
rjr02_q01: 1
};
const AntDFormChild = ({ form }) => {
const [isQualified, setIsQualified] = useState(false);
const [questionFormValues, setQuestionFormValues] = useState({});
useEffect(() => {
if (shallowEqual(questionFormValues, questionQualifiedValues)) {
setIsQualified(true);
} else {
setIsQualified(false);
}
}, [questionFormValues]);
function shallowEqual(object1, object2) {
const keys1 = Object.keys(object1);
const keys2 = Object.keys(object2);
if (keys1.length !== keys2.length) {
return false;
}
for (let key of keys1) {
if (object1[key] !== object2[key]) {
return false;
}
}
return true;
}
return (
<>
{isQualified && (
<div style={{ color: "red" }}>You checked all answered with yes</div>
)}
<Form.Item name="rjr01_q01" label="Question 1">
<Radio.Group
onChange={(i) => {
setQuestionFormValues((questionFormValues) => ({
...questionFormValues,
rjr01_q01: i.target.value
}));
}}
>
<Radio value={1}>Yes</Radio>
<Radio value={0}>No</Radio>
<Radio value={2}>Unknown</Radio>
</Radio.Group>
</Form.Item>
<Form.Item name="rjr02_q01" label="Question 2">
<Radio.Group
onChange={(i) => {
setQuestionFormValues((questionFormValues) => ({
...questionFormValues,
rjr02_q01: i.target.value
}));
}}
>
<Radio value={1}>Yes</Radio>
<Radio value={0}>No</Radio>
<Radio value={2}>Unknown</Radio>
</Radio.Group>
</Form.Item>
</>
);
};
Share
Improve this question
edited Dec 1, 2021 at 16:22
BenjaminK
asked Dec 1, 2021 at 16:17
BenjaminKBenjaminK
8331 gold badge13 silver badges33 bronze badges
0
1 Answer
Reset to default 3Since AntD Form is uncontrolled, there is no way to trigger onChange
event by calling resetFields
, setFieldsValues
.
I think your goal is to show the message depending on form values, and the best way to do is to use Form.Item
, which can access form state.
https://codesandbox.io/s/antd-form-item-based-on-other-item-ens59?file=/src/AntDFormChild.js
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745664682a4639052.html
评论列表(0条)