【问题标题】:Dynamic validations for programmatically rendered Redux Fields以编程方式呈现的 Redux 字段的动态验证
【发布时间】:2019-07-02 18:19:43
【问题描述】:

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

我有一个简单的 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 对象,以及它们何时被 visited、touch编辑等。

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

syncErrors: {
  firstName: 'Must be at least 2 characters'
}

然后我想在firstName 输入下显示一条错误消息,但在lastName 输入下没有任何内容。同样,如果lastNamesyncErrors 对象的一部分,那么该输入下也会显示错误。如果firstNamelastName 都在syncErrors 中,那么两个输入下都会显示错误。

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

谢谢!

【问题讨论】:

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


    【解决方案1】:

    如果您将错误消息作为道具传递给Field 组件,那么您可能只想向Field 组件添加一些代码,如果有错误则显示错误。它应该看起来像这样: {this.props.error ? (&lt;p&gt;{this.props.error}&lt;/p&gt;) : 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>
      );
    }
    

    【讨论】:

    • 是的,我通常会这样做。不幸的是,我用 Redux Field 包装的 FormField 组件来自一个 UI Kit,它是一个 npm 包,另一个团队正在开发它,我无法编辑。 error 属性应该只显示错误(如果有),或者什么也不显示。我正在尝试显示正确输入的错误,而不显示两个输入的错误,即使只有 1 未通过验证...
    • @Lushmoney,请查看我的新编辑,看看是否能令人满意地解决您的问题
    【解决方案2】:

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

    ...
    
    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 对象将填充表单字段名称作为键,验证错误(错误消息)作为值。 p>

    此外,当表单因验证失败而提交失败时,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!

    【讨论】:

      猜你喜欢
      • 2019-11-12
      • 2021-02-11
      • 2017-12-09
      • 2017-12-27
      • 2018-09-08
      • 2021-09-07
      • 2010-12-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多