#javascript #reactjs #antd
#javascript #reactjs #antd
Вопрос:
У меня есть <Form>
компонент Ant Design с несколькими <Form.Items>
. Одним из них является a <Select>
, который зависит от нескольких других <Form.Item>
состояний для изменения <Options>
стиля в зависимости от комбинации выбранных значений в другом <Form.Items>
. Я работаю с дополнительным объектом useState ( activeQuestions
), чтобы упростить обработку более сложных комбинаций. Моя проблема в том, что когда форма сбрасывается form.resetFormFields()
или устанавливается, form.setFieldsValue()
она не будет вызывать мои используемые события onChange, поскольку форма antd является неконтролируемой формой. Так что я не уверен, как подойти к этому. Существует shouldUpdate on <Form.Items>
, но я не уверен, как и если это правильный подход для этой цели.
Итак, в созданном мной упрощенном примере изолированной среды при изменении всех значений <Radio>
на Yes запускается событие onChange, которое проверяется, а затем некоторые параметры выбора становятся серыми. Но при использовании одной из двух кнопок сверху reset или fill это не обновит состояние.
Есть ли что-то в форме Ant Design, чего мне не хватает? Потому что это должно быть обычной задачей. Каков хороший способ решения этой проблемы?
Ссылка на изолированную среду кода с примером:
https://codesandbox.io/s/antd-form-item-based-on-other-item-forked-zofnj?file=/src/AntDFormChild.js
Что я пробовал (это вызывает бесконечный цикл)
<Form.Item
noStyle
shouldUpdate={(prevValues, currentValues) => {
console.log(prevValues.rjr01_q01, currentValues.rjr01_q01);
return (
prevValues.rjr01_q01 !== currentValues.rjr01_q01 amp;amp;
prevValues.rjr02_q01 !== currentValues.rjr02_q01
);
}}
>
{({ getFieldValue }) => {
setSelections((selections) => ({
rjr01_q01: getFieldValue("rjr01_q01"),
rjr02_q01: getFieldValue("rjr02_q01")
}));
return null;
}}
</Form.Item>
Пример
import React, { useState, useEffect } from "react";
import { Descriptions, Form, Radio, Select, Typography } from "antd";
const { Text } = Typography;
const { Option } = Select;
const questionsData = {
rjr01_q01: { title: "Question 1", description: "Question 1 description" },
rjr02_q01: { title: "Question 2", description: "Question 2 description" }
};
const AntDFormChild = ({ form }) => {
const [selections, setSelections] = useState({
rjr01_q01: null,
rjr02_q01: null
});
const [activeQuestions, setActiveQuestions] = useState([]);
useEffect(() => {
console.log("selections state update", selections);
// if question 1 is yes
if (selections.rjr01_q01 === 1 amp;amp; !activeQuestions.includes("rjr01_q01")) {
setActiveQuestions((activeQuestions) => [
...activeQuestions,
"rjr01_q01"
]);
}
// if question 1 is not yes
if (selections.rjr01_q01 !== 1 amp;amp; activeQuestions.includes("rjr01_q01")) {
setActiveQuestions((activeQuestions) => [
...activeQuestions.filter((i) => i !== "rjr01_q01")
]);
}
// if question 2 is yes
if (selections.rjr02_q01 === 1 amp;amp; !activeQuestions.includes("rjr02_q01")) {
setActiveQuestions((activeQuestions) => [
...activeQuestions,
"rjr02_q01"
]);
}
// if question 2 is not yes
if (selections.rjr02_q01 !== 1 amp;amp; activeQuestions.includes("rjr02_q01")) {
setActiveQuestions((activeQuestions) => [
...activeQuestions.filter((i) => i !== "rjr02_q01")
]);
}
}, [selections]);
useEffect(() => {
console.log("activeQuestions state update", activeQuestions);
}, [activeQuestions]);
return (
<>
<Form.Item
noStyle
shouldUpdate={(prevValues, currentValues) => {
console.log(prevValues.rjr01_q01, currentValues.rjr01_q01);
return (
prevValues.rjr01_q01 !== currentValues.rjr01_q01 amp;amp;
prevValues.rjr02_q01 !== currentValues.rjr02_q01
);
}}
>
{({ getFieldValue }) =>
getFieldValue("rjr01_q01") === 1 amp;amp;
getFieldValue("rjr02_q01") === 1 ? (
<div style={{ color: "red" }}>
You checked all answered with yes
</div>
) : null
}
</Form.Item>
<Form.Item name="rjr01_q01" label="Question 1">
<Radio.Group
onChange={(i) => {
setSelections((selections) => ({
...selections,
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) => {
setSelections((selections) => ({
...selections,
rjr02_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="availableQuestions" label="Available Questions">
<Select allowClear style={{ width: 250 }}>
{Object.keys(questionsData).map((key, index) => (
<Option key={key} value={key}>
<Text
style={{
color: activeQuestions.includes(key) amp;amp; "lightgrey"
}}
>
{questionsData[key].title}
</Text>
</Option>
))}
</Select>
</Form.Item>
</>
);
};
export default AntDFormChild;