Making Simple Object Schema Validation even Simpler with React Custom Hooks and YUP!
We have projects and components in choreo. Oh if you don’t know what choreo is, go check this out. So, for every project, there should be a name. For every component, there should be a name. But first, the names should be validated. It is expected to have some rules configured for these names and in choreo for a component/project name we expect it,
- To have at least 3 letters
- Not to have special characters
- To have the first letter an alphabetic
Basically, this is form validation and the expected outcome looks something like this; if we enter a name with less than 3 letters:
When we were given such kind of a task, the first thing we try to do is come up with a RegEx to check and validate the string. But in this case, we have multiple rules to be checked and if we are using vanilla regex this will be not easy (It can be done but it will get more and more complex when we add more rules in the future).
That’s where the Yup library comes in! Yup is a schema builder for runtime value parsing and validation. Define a schema, transform a value to match, assert the shape of an existing value, or both. Yup schema is extremely expressive and allows modeling complex, interdependent validations, or value transformation.
As I mentioned earlier let’s see how we integrated the Yup to our choreo console text validations.
This is a high-level diagram that shows how and what we need to do validation and what we get in return.
Let me explain these items in the diagram one by one.
- Input string — The string we need to validate; for example, ‘GR’ from the above screenshot.
- Schema — Most important item in this process. This contains all the rules which needed to be checked and validated; for example ‘The component name must have at least 3 letters from the above screenshot.
- YUP — The main library logic
- Isvalid — Boolean value which indicates whether the given string is valid or not; in the above screenshot, the value is false. Why do we need this? We need this to disable the save/next button because we should not allow the user to continue with an invalid component name.
- Error Helper Text — when something goes wrong; in other words, the given string is not fulfilling the rules we should indicate that to the user right? So this helper text will show what’s wrong with the string if it is invalid; again on the screenshot ‘the red text under the box’ is the helper text.
You may remember that I told you that we use this validation for component names and project names as well right? So did we re-write the code in both places? No, that’s where the custom react hook comes to play. The validate function is exposed so that it can be easily used from any component to validate a string with a given schema.
Let me share with you the react hook I wrote.
Let me briefly explain the above code. First, we have the input param of the schema which defines the rules for the validation. Then we have the return types: isValid, errorHelperText, and the validate function. After that, we have some local states to handle the boolean and the text mentioned. Finally, the main method, validate. Since we have the schema defined we can simply use the validateSync method. We should wrap the method inside a try-catch block and catch the errors which are violated during validation.
Let’s say we have multiple rule violations in a single string. So that’s why this abortEarly is required. If we set that to true whenever an error is thrown the loop will be broken and we always get the first rule violation on the nameError object. If we set that to false we can get all the violations in a form of an array from the nameError object.
The schema? Here’s an example schema with the rules I mentioned earlier. Additionally, we have set custom error messages so that we can override the error text which is thrown when a rule is violated.
We can simply use this hook like this,
So that’s how we can build a simple but powerful string validation hook. Hope you gain something from this. Thanks for reading and see you in the next post. Peace!