以编程方式呈现的Redux字段的动态验证

时间:2019-07-02 18:19:43

标签: javascript reactjs redux react-redux redux-form

无法找到我遇到的问题的直接答案,所以希望有人能帮助我...

我有一个简单的Redux表单,其中只有一个First NameLast Name输入字段。这些字段不是通过显式写出的,而是以编程方式呈现的,如下所示:

...

renderNameInput(field) {
  const { content } = this.props;

  return (
    <Field
      id={field}
      name={field}
      component={FormField}
      validate={this.nameValidations}
      error={!this.isNameValid(field) ? content.nameError : null}
    />
  );
}

...

render() {
  <form onSubmit={handleSubmit}>
    <div>
      {this.renderNameInput('firstName')}
      {this.renderNameInput('lastName')}
    </div>
  </form>
}

我遇到的问题是,当字段未通过验证时显示错误。每个字段至少需要2个字符,最多16个字符(尽管这与我的特定问题无关)。

我想做的是,当输入之一无效时,该输入下将显示错误。如果两个输入均无效,则错误将显示在两个输入下方(用于显示其相应位置的错误的结构和样式当然已经完成,只是该问题的一部分

这是我检查错误的方法:

...

isNameValid(field) {
  const { formState = {} } = this.props;
  const { syncErrors } = formState;

  if (syncErrors && syncErrors[field]) {
    return false;
  }
}

...

该组件已连接到Redux存储,因此我可以访问表单中的formStateinitialvalues对象,以及访问{{ 1}},visit等,

如果-当用户更改输入值时-touch对象在查看商店中的Redux状态(任意)时看起来像这样:

syncErrors

然后,我希望在syncErrors: { firstName: 'Must be at least 2 characters' } 输入下显示一条错误消息,但在firstName输入下不显示任何错误消息。同样,如果lastNamelastName对象的一部分,那么错误也将在该输入下显示。如果syncErrorsfirstName都在lastName中,则在两个输入下都会显示错误。

我希望这有道理,有人可以指出我正确的方向。如果需要任何澄清,请告诉我。

谢谢!

2 个答案:

答案 0 :(得分:1)

如果您将错误消息作为对Field组件的支持,那么您可能只想向Field组件添加一些代码,如果有的话就会显示错误是一个。它看起来应该像这样: {this.props.error ? (<p>{this.props.error}</p>) : null}

由于您无法更改Field组件中显示的内容,因此建议您允许存在renderNameInput的组件访问Redux中的错误对象。这样,您可以使renderNameInput返回Field组件和错误消息。像这样:

renderNameInput(field) {
  const { content, error } = this.props;

  return (
    <div>
      <Field
        id={field}
        name={field}
        component={FormField}
        validate={this.nameValidations}
        error={!this.isNameValid(field) ? content.nameError : null}
      />
      <p>{error[field] ? (<p>{error[field]}</p>) : null}}</p>
    </div>
  );
}

答案 1 :(得分:1)

我实际上能够弄清楚这一点。我做了这个方法:

...

isNameError(field) {
  const { content, formState = {}, submitFailed } = this.props;
  const { initial, syncErrors, values } = formState;

  if (!submitFailed || !syncErrors) {
    return null;
  }

  const isNotSameValues = initial[field] !== values[field];
  const invalidField = Boolean(isNotSameValues && syncErrors[field]);

  if (invalidField) {
    return content.nameError;
  }
}

...

由于此组件是用reduxForm包装的,所以我可以使用传递到包装后的组件的某些道具-submitFailedsyncErrors。如果表单字段未通过我的验证检查,则将使用表单字段名称作为键并以验证错误(错误消息)作为值来填充syncErrors对象。

另外,当由于验证失败而导致提交表单失败时,submitFailed属性(布尔值)也设置为true

我将组件连接到Redux存储,因此能够访问formState,并使用initialvalues道具来比较每个输入字段的值并进行验证检查。

在我最初的renderNameInput方法中使用它的方式如下:

...

renderNameInput(field) {
  const { content, formState = {}, submitFailed } = this.props;

  const label = get(content, `${field}Field.text`, '');

  return (
    <Field
      id={field}
      name={field}
      component={FormField}
      validate={this.nameValidations}
      error={isNameError(field)}
    />
  );
}

...

每个输入字段都经过单独验证,如果未通过初始提交的检查,则错误消息将显示在每个输入下方。该输入通过检查后,错误就会消失,我可以提交。

@ldtcoop非常感谢您的帮助!