react-hook-form: Allow React components to be returned as `validate` rule error message

Hello,

Is your feature request related to a problem? Please describe. My issue is that the validate method only allows to return a bool or a string, and returning a React component will not validate as an error. Being able to set a React component as an error message would allow for more complex and useful (UI-wise) error handling. As an example, consider a password input with a dynamic rule checking for its constraints (required characters, length, etc.). The validate method works very well with this kind of complex rule checks, but I would also like to be able to give instant feedback as the user types a password, via a react component instead of a string.

I would also like to point out that setting a component as an error message in the other validation methods works (I tried with pattern) (

register({
    pattern({
        value: /regex/,
        message: component
    }),
})

).

Describe the solution you’d like I’d like the validate method to accept a React component as a possible return type, to be handled as a message error.

Describe alternatives you’ve considered None.

Additional context To give you a more concrete example, here is a condensed snippet of what I am trying to do:

register({
    validate: customValidate, 
})
customValidate: value => {
    const constraints = {
        hasMinLen: value.length >= 8,
        hasUppercase: /([A-Z]+)/.test(value),
        hasLowercase: /([a-z]+)/.test(value),
        hasNumber: /([0-9]+)/.test(value),
    };

     return (
         Object.values(constraints).every(constraint => constraint) || (
            <span>
                Le mot de passe doit contenir au moins:
                <div className="tags">
                    {!constraints.hasMinLen && (
                        <span className="tag is-danger">8 caractères</span>
                    )}
                    {!constraints.hasLowercase && (
                        <span className="tag is-danger">1 minuscule</span>
                    )}
                    {!constraints.hasUppercase && (
                        <span className="tag is-danger">1 majuscule</span>
                    )}
                    {!constraints.hasNumber && (
                        <span className="tag is-danger">1 chiffre</span>
                    )}
                </div>
            </span>
         )
    );
}

Thank you very much for your attention!

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 18 (11 by maintainers)

Most upvoted comments

@bluebill1049 I will try this! Thanks 👍

That was quick! Thanks a lot @kotarella1110 and @bluebill1049

I’m eager to use this in my app, how can I pull this version via yarn or npm? I tried upgrading the package (I’m on 5.1.3), but I don’t seem to be able to use the feature. Or should I wait for you to update the package with a new version?

Thanks again!

@kotarella1110 I think we don’t need vote for this one anymore. we should support it due to consistency. I didn’t want to remove JSX due to existing functionality because it will be a breaking change.

That’s what I thought, thanks for your work and understanding!

@starmatt This feature is not yet released. Perhaps it will be released by a few days. You can test this out: https://codesandbox.io/s/react-hook-form-issue-1266-khtse

Hi @kotarella1110 , thanks for your directives!

I’m trying to make this work with my current codebase, but I would have to rework a lot of how I currently build my input components, so I don’t think it’ll be worth it with reusability in mind. I’ll keep trying but if I can’t make it work I’ll stick to pattern for this input.

It’s definitely a good alternative though, but I still think allowing users to set JSX in error messages would improve your already awesome lib!

Here’s a codebox example: https://codesandbox.io/s/nervous-khayyam-r6i40 I took time to test all the functions, and it works with JSX only for functions that takes a value/message object.

FYI validateField.ts is the one you want to take a look at.

are you interested to take on this one? @kotarella1110 otherwise i will be looking into this over the weekend. I don’t think we are in a rush with this.

@starmatt How about this?

useForm<FormData>({
  validateCriteriaMode: "all"
});
register({
  validate: {
    hasMinLen: value => value.length >= 8 || "8 caractères",
    hasUppercase: value => /([A-Z]+)/.test(value) || "1 minuscule",
    hasLowercase: value => /([a-z]+)/.test(value) || "1 majuscule",
    hasNumber: value => /([0-9]+)/.test(value) || "1 chiffre"
  }
})
<ErrorMessage name="test" errors={errors}>
  {({ messages }) =>
    messages && (
      <span>
        Le mot de passe doit contenir au moins:
        <div className="tags">
          {Object.entries(messages).map(([type, message]) => (
            <span key={type} className="tag is-danger">
              {message}
            </span>
          ))}
        </div>
      </span>
    )
  }
</ErrorMessage>

codesandbox: https://codesandbox.io/s/react-hook-form-issue-1266-9t2z4