我有一个带有受控输入元素的表格。输入可能具有验证,并且它们正在onBlur
上发生,并且如果用户在“提交”按钮上进行了onClick
。如果验证状态在检查后发生更改(删除或添加错误),则它将以React setState
的形式存储在React状态。如果验证状态未更改(未添加错误或未删除),则提交立即发生。如果出现错误,但单击后验证成功,则onBlur
会触发并引起状态更改,并且甚至不会触发onClick
,因此只需单击两次即可提交。
completeProcess = (val, process, maxLen) => process(val).substr(0, maxLen)
//called inside render
renderInputs = () => this.props.inputs.map(input => {
const {
id,
validation,
required = true,
label,
initValue = "",
className = "",
placeholder = "",
type = "text",
tag = "input",
options = [],
process = v => v,
minLen = 0,
maxLen = 20000
} = input;
const value = this.state[id] ? this.state[id].value : initValue;
const error = this.state[id] ? this.state[id].error : null;
const onBlur = () => {
console.log("blur")
this.setState({ [id]: {
...this.state[id],
error: validate({value, validation, required, minLen})
}});
};
const onChange = ({ target: { value: newValue }}) => this.setState(
{ [id]: {
...this.state[id],
value: process(newValue)
}}
);
return (
<Input
className={className}
label={label}
placeholder={placeholder}
value={value}
onBlur={onBlur}
onChange={onChange}
type={type}
tag={tag}
options={options}
key={id}
id={id}
error={error}
/>
);
})
//called on submit button click
handleSubmit = () => {
console.log("submit")
const inputProps = this.state;
const errors = {};
const processedValues = {};
this.props.inputs.map(
({
id,
required = true,
validation,
process = v => v,
minLen = 0,
maxLen = 20000
}) => {
const { value } = inputProps[id];
errors[id] = validate(
{value, validation, required, minLen}
);
processedValues[id] = this.completeProcess(
value, process, maxLen
);
}
);
const errorFree = Object.values(errors).every(e => !e);
if (errorFree) {
this.props.onSubmit(processedValues);
} else {
const newState = {};
Object.keys(inputProps).forEach(id => {
const { value } = inputProps[id];
const error = errors[id];
newState[id] = { value, error };
});
this.setState(newState);
}
}