我在进行表单验证时遇到问题。我有一个功能:
const inputValid = name => {
const isValid = localState.validationExpressions[name].test(
localState.values[name]
);
if (isValid) {
if (localState.values[name]) {
setLocalState({
...localState,
labelClasses: {
...localState.labelClasses,
[name]: 'input-group__label input-group__label--filled',
},
fieldClasses: {
...localState.fieldClasses,
[name]: 'input-group__field',
},
withMessage: {
...localState.withMessage,
[name]: false,
},
});
} else {
setLocalState({
...localState,
labelClasses: {
...localState.labelClasses,
[name]: 'input-group__label',
},
fieldClasses: {
...localState.fieldClasses,
[name]: 'input-group__field',
},
withMessage: {
...localState.withMessage,
[name]: false,
},
});
}
} else {
if (localState.values[name]) {
setLocalState({
...localState,
labelClasses: {
...localState.labelClasses,
[name]:
'input-group__label input-group__label--filled input-group__label--danger',
},
fieldClasses: {
...localState.fieldClasses,
[name]: 'input-group__field input-group__field--danger',
},
withMessage: {
...localState.withMessage,
[name]: true,
},
});
} else {
setLocalState({
...localState,
labelClasses: {
...localState.labelClasses,
[name]: 'input-group__label input-group__label--danger',
},
fieldClasses: {
...localState.fieldClasses,
[name]: 'input-group__field input-group__field--danger',
},
withMessage: {
...localState.withMessage,
[name]: false,
},
});
}
}
return isValid;
};
初始状态:
const initialState = {
values: {
name: '',
unit: '',
kcal: '',
fat: '',
carbohydrates: '',
protein: '',
portion: '',
},
labelClasses: {
name: 'input-group__label',
unit: 'input-group__label input-group__label--radio',
kcal: 'input-group__label',
fat: 'input-group__label',
carbohydrates: 'input-group__label',
protein: 'input-group__label',
portion: 'input-group__label',
},
fieldClasses: {
name: 'input-group__field',
unit: 'input-group__radio',
kcal: 'input-group__field',
fat: 'input-group__field',
carbohydrates: 'input-group__field',
protein: 'input-group__field',
portion: 'input-group__field',
},
validationExpressions: {
name: new RegExp('^[a-zA-Z0-9ąęćłńóśźż]+[a-zA-Z0-9\\s]*$', 'i'),
unit: new RegExp('^(g|ml)$'),
kcal: new RegExp('^[0-9]+\\.?[0-9]{0,2}$'),
fat: new RegExp('^[0-9]+\\.?[0-9]{0,2}$'),
carbohydrates: new RegExp('^[0-9]+\\.?[0-9]{0,2}$'),
protein: new RegExp('^[0-9]+\\.?[0-9]{0,2}$'),
portion: new RegExp('^([1-9]|[1-9][0-9]*)?$'),
},
withMessage: {
name: false,
unit: false,
kcal: false,
fat: false,
carbohydrates: false,
protein: false,
portion: false,
},
};
当我在处理模糊事件时调用该函数时,一切似乎都正常工作-每个状态都单独更新,旧效果保持在状态中,模糊输入获得新的classNames。
但是我也想将这种机制实现为提交,我多次调用此函数:
const handleSubmit = e => {
e.preventDefault();
inputValid('fat');
inputValid('carbohydrates');
callback();
};
似乎从上次调用开始只有一部分状态被更新(或先前的状态被覆盖为默认状态)。
我想在Submit调用中逐一验证所有输入。任何帮助将不胜感激。
答案 0 :(得分:0)
我认为您可以在那里使用Formik
库。它非常酷,可以满足您的需求。
我在这里创建了一个演示-https://formfieldreact.stackblitz.io
这是代码:https://stackblitz.com/edit/formfieldreact
让我知道您是否有任何问题?
答案 1 :(得分:0)
好吧,经过几个小时的测试和搜索,我找到了答案-对于那些可能遇到相同问题的人。基于类的组件中的setState可能是异步的;来自react docs:
状态更新可能是异步的 React可以将多个setState()调用批处理为一个更新,以提高性能。
由于this.props和this.state可能是异步更新的,因此不应依赖于它们的值来计算下一个状态。
它不保证修改后的状态为最新状态。根据我的组件的输出,useState挂钩的工作方式完全相同-当连续多次调用其中一个时,状态不会每次都更新。本文中有关该主题的更多信息:
为避免这种情况,在处理以前的状态时,应使用函数而不是对象作为参数来调用setState(或来自hook的setLocalState)。
react docs中的代码:
use itertools::Itertools; // 0.8.2
use std::collections::HashMap;
fn main() {
let mut m = HashMap::<String, String>::new();
m.insert("a".to_string(), "1".to_string());
m.insert("b".to_string(), "2".to_string());
m.insert("c".to_string(), "3".to_string());
m.insert("d".to_string(), "4".to_string());
println!("{:#?}", m.iter().sorted())
}