React动态表单组件技术问题:输入字段为空时提交按钮无法禁用(validateResult函数未返回false)
解决DynamicForm提交按钮禁用问题
我一眼就看出你的validateResult函数逻辑完全不对,这就是为啥按钮永远不会禁用的原因!咱们一步步来修复:
问题分析
原函数里的if (inputs[res] === 0)完全没有意义——你传入的res是整个inputs数组,这行判断永远不会成立,所以函数一直返回true,导致disabled={!validateResult(inputs)}永远是false,按钮始终可用。
正确的逻辑应该是:检查result状态中所有对应表单字段的值是否都为空,如果全为空就返回false(让按钮禁用),否则返回true。
修复步骤
- 重写
validateResult函数:遍历传入的表单配置data,检查result中每个字段的状态是否为空(包括undefined、空字符串、0这类空值) - 修复组件内的遍历来源:你现在用的是全局的
inputs数组遍历渲染输入框,但组件props里已经传入了data,应该用data.map来保持组件的通用性 - 调整按钮禁用逻辑:让
disabled绑定的逻辑更清晰 - 修正样式类名错误:你之前把组件本身当成类名传入了
cn,这是无效的,需要移除
完整修复后的代码
import cn from "classnames"; import styles from "./DynamicForm.module.sass"; import { Card } from "../Card"; import { TextInput } from "../TextInput"; import { Button } from "../Button"; type DynamicInput = StringInput | NumberInput; interface StringInput { type: "text"; name: string; label: string; value?: string; placeholder: string; min: number; max: number; } interface NumberInput { type: "number"; name: string; label: string; value?: number; placeholder: string; min: number; max: number; } interface DyanamicFormResult { [name: string]: any; } interface DynamicFormProps { data: DynamicInput[]; onSubmit: (result: DyanamicFormResult) => void; } export const inputs: DynamicInput[] = [ { type: "text", name: "Parameter1", label: "Parameter1", placeholder: "placeholder1", min: 2, max: 17, }, { type: "number", name: "Parameter2", label: "Parameter2", placeholder: "placeholder2", min: 4, max: 17, }, ]; export const DynamicForm: React.FC<DynamicFormProps> = ({ data, onSubmit }) => { const [result, setResult] = React.useState<DyanamicFormResult>({}); const onClick = () => { onSubmit(result); }; const handleChange = (attribName: string, value: any) => { setResult({ ...result, [attribName]: value }); }; // 重写验证函数:检查所有字段是否都为空 const validateResult = () => { // 遍历所有表单配置项,检查对应result中的值是否为空 const allFieldsEmpty = data.every(input => { const fieldValue = result[input.name]; // 判断空值:可根据需求调整,比如如果数字0是有效输入,就去掉===0 return fieldValue === undefined || fieldValue === '' || fieldValue === 0; }); // 如果所有字段都为空,返回false(让按钮禁用),否则返回true return !allFieldsEmpty; }; return ( <div> <Card title="Header" classTitle="title-blue"> {/* 改用props传入的data遍历,保证组件通用性 */} {data.map((input) => ( <TextInput key={input.name} className={cn(styles.txt)} type={input.type} name={input.name} value={result[input.name] || input.value} label={input.label} placeholder={input.placeholder} onChange={(event: any) => handleChange(input.name, event.target.value) } /> ))} <Button className={cn(styles.btn)} label="Submit" variant="button" small={true} onClick={onClick} disabled={!validateResult()} /> </Card> </div> ); };
额外说明
- 验证函数里的空值判断可以根据你的需求调整:比如如果数字输入框的
0是有效输入,你可以去掉fieldValue === 0这部分 - 现在组件使用props传入的
data来渲染输入框,这样你的DynamicForm组件可以复用在不同的表单场景,而不是只能依赖全局的inputs数组
内容的提问来源于stack exchange,提问作者segsyllama
相关产品推荐
相关产品推荐

