Kendo React自定义FormDropDownList表单提交值不显示问题排查
问题原因分析
核心问题:未触发表单字段的状态更新
Kendo React Form的Field组件通过onChange回调同步字段值到表单全局状态。你的自定义FormDropDownList仅维护了内部的currentValue状态,但下拉选项变化时,没有调用Field传递的onChange方法,导致表单完全不知道字段值已变更,提交时自然拿不到最新选中值。
其他辅助问题
- useEffect依赖缺失:当前
useEffect依赖数组为空,父组件传递的data或value更新时,组件不会重新加载默认数据,可能导致初始值显示异常。 - 初始值处理不严谨:
currentValue初始化为空对象,若表单字段有初始值,可能无法正确匹配显示。
修复方案
1. 下拉框变化时同步表单状态
修改onValueChange函数,更新内部状态的同时,调用Field传递的onChange,将选中值同步到表单:
const onValueChange = (event) => { const cData = event.target.value; setCurrentValue(cData); // 调用Form Field的onChange,传递选中值的对应字段(匹配dataItemKey指定的键) onChange({ target: { name: name, value: cData[dataItemKey] } }); };
注:这里传递
dataItemKey对应的字段值(比如示例中的module数字ID),因为表单字段name="module"期望的是该类型值,而非整个选中对象。
2. 修复useEffect依赖数组
将data和value加入依赖数组,确保父组件数据或初始值变化时,组件能重新加载默认数据:
React.useEffect(() => { setState(data); loadDefaultData(data); }, [data, value]); // 添加依赖项
3. 优化初始值初始化
直接从data中匹配初始value,避免初始为空对象:
const [currentValue, setCurrentValue] = React.useState(() => { return data.find((obj) => obj[dataItemKey] === value) || {}; });
完整修复后的FormDropDownList代码
import * as React from "react"; import { FieldWrapper } from "@progress/kendo-react-form"; import { Label, Error, Hint } from "@progress/kendo-react-labels"; import { DropDownList } from "@progress/kendo-react-dropdowns"; import axios from "axios"; export const FormDropDownList = (fieldRenderProps) => { const { validationMessage, touched, label, id, valid, disabled, hint, wrapperStyle, dropdownType, data, value, name, style, onChange: formOnChange, // 重命名避免混淆 dataItemKey, textField, ...others } = fieldRenderProps; const [state, setState] = React.useState(data); const [currentValue, setCurrentValue] = React.useState(() => { return data.find((obj) => obj[dataItemKey] === value) || {}; }); const onValueChange = (event) => { const cData = event.target.value; setCurrentValue(cData); // 同步选中值到Form formOnChange({ target: { name: name, value: cData[dataItemKey] } }); }; React.useEffect(() => { setState(data); const matchedData = data.find((obj) => obj[dataItemKey] === value) || {}; setCurrentValue(matchedData); }, [data, value, dataItemKey]); const editorRef = React.useRef(null); const showValidationMessage = touched && validationMessage; const showHint = !showValidationMessage && hint; const hintId = showHint ? `${id}_hint` : ""; const errorId = showValidationMessage ? `${id}_error` : ""; const labelId = label ? `${id}_label` : ""; return ( <FieldWrapper style={wrapperStyle}> <Label id={labelId} editorRef={editorRef} editorId={id} editorValid={valid} editorDisabled={disabled} > {label} </Label> <DropDownList onChange={onValueChange} ariaLabelledBy={labelId} ariaDescribedBy={`${hintId} ${errorId}`} ref={editorRef} valid={valid} id={id} name={name} value={currentValue} disabled={disabled} data={state} dataItemKey={dataItemKey} textField={textField} style={style} /> {showHint && <Hint id={hintId}>{hint}</Hint>} {showValidationMessage && <Error id={errorId}>{validationMessage}</Error>} </FieldWrapper> ); };
内容的提问来源于stack exchange,提问作者Black
相关产品推荐
相关产品推荐

