RxJs forms in React - Part 2
In Part 1 of this post I was experimenting with a simple React form component that would allow a form to be declared using standard form elements, and which would return an rxjs observable with which to access changes in the form inputs.
After playing around with this approach I came to the conclusion that the observables did not add enough value to outweigh the additional complexity. This is mostly because of the simple need I had to only validate and get back the form data on the final submit, rather than on every change in the form.
I went ahead and completed the library anyway, but just using standard React APIs. One of the main things I wanted to achieve was to automatically add the additional validation error markup, which turned out to be relatively easy with React.createElement.
To enable validation I just added a simple prop which indicates the validation type. Then form component fields, with the validation prop set, are replaced with a new element that wraps the original field and a Validation component:
The world doesn't need another React form library, so no plans to take this too much further at this stage. However, I may still tidy it up to use on some personal projects, so the final outcome of this will be available here if anyone is interested.
After playing around with this approach I came to the conclusion that the observables did not add enough value to outweigh the additional complexity. This is mostly because of the simple need I had to only validate and get back the form data on the final submit, rather than on every change in the form.
I went ahead and completed the library anyway, but just using standard React APIs. One of the main things I wanted to achieve was to automatically add the additional validation error markup, which turned out to be relatively easy with React.createElement.
To enable validation I just added a simple prop which indicates the validation type. Then form component fields, with the validation prop set, are replaced with a new element that wraps the original field and a Validation component:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// where the form is declared a simple string is used to indicated validation type | |
<input name="firstName" validation="required" /> | |
// an object map is used in the form library to map this string name to a validation method and message | |
export const validationTypes = { | |
required: { validate: validateRequired, message: 'Field is required' }, | |
email: { validate: validateEmail, message: 'Valid email address required' } | |
} | |
// a functional component is used to display validation errors | |
const ValidationError = ({ invalid, message }) => { | |
return ( | |
<div> | |
{invalid && | |
<span>{message}</span> | |
} | |
</div> | |
); | |
} | |
// within the form library any fields with the validation prop are replaced with a new div | |
// that wraps the field and the validation component. An invalidFields object is added the | |
// field component state to dictate if validation errors should be shown for individual fields | |
addValidationToField(field) { | |
let validation = field.props.validation; | |
return React.createElement('div', null, | |
field, | |
React.createElement(ValidationError, { | |
invalid: this.state.invalidFields[field.props.name], | |
message: this.validationTypes[validation].message | |
}, null)); | |
} |
Comments
Post a Comment