反应提交验证

时间:2019-11-25 14:44:49

标签: reactjs forms

我在进行表单验证时遇到问题。我有一个功能:

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调用中逐一验证所有输入。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

我认为您可以在那里使用Formik库。它非常酷,可以满足您的需求。

我在这里创建了一个演示-https://formfieldreact.stackblitz.io

这是代码:https://stackblitz.com/edit/formfieldreact

让我知道您是否有任何问题?

答案 1 :(得分:0)

好吧,经过几个小时的测试和搜索,我找到了答案-对于那些可能遇到相同问题的人。基于类的组件中的setState可能是异步的;来自react docs:

  

状态更新可能是异步的   React可以将多个setState()调用批处理为一个更新,以提高性能。

由于this.props和this.state可能是异步更新的,因此不应依赖于它们的值来计算下一个状态。

它不保证修改后的状态为最新状态。根据我的组件的输出,useState挂钩的工作方式完全相同-当连续多次调用其中一个时,状态不会每次都更新。本文中有关该主题的更多信息:

React antipatterns

为避免这种情况,在处理以前的状态时,应使用函数而不是对象作为参数来调用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())
}