An exploration of using Fragments in React with state.
Fragments were highlighted in React 16.2 back in November 2017 https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html and there are plenty of examples out there showing simple usage:
This is useful as it saves the additional wrapping of children in extra elements such as a div or span.
It’s worth noting the syntax for a
Fragment can also be expressed explicitly, and whilst I’m all for the shortening of code I think I prefer the readability this provides instead, so the above can be written either as:
I’ll leave the preference of which to use up to you, but for this I’m going to use
I recently started to use the Material-UI library https://material-ui.com/ . In the examples provided there was a Checkout demo, the source code of which is found here: https://github.com/mui-org/material-ui/tree/master/docs/src/pages/page-layout-examples/checkout
This demo used fragments to render the component parts for each step in the process, however there was no validation of the fields and the review form mock up ignoring previous inputs. This made me wondered how I might add these checks and functionality to this example.
The example code is segmented into four parts, an AddressForm, PaymentForm, Review step and the main Checkout component. Of these, Address, Payment and Review are Fragments which are accessed in the main component via:
The Review needed access to the details added in both the AddressForm and PaymentForm and I wanted to limit progress through the steps if the required fields were not valid.
To try this out I used
create-react-app to startup a demo and copied the code from the repository to here adding in the Material-UI dependencies and removing the starter css.
In the main Checkout form I added state for the respective areas:
Along with a validation property to manage that side of the process. I added the handleChange function and passed both of these to the Fragments:
This allowed the Checkout state to be updated from the Fragments. In the AddressForm for the required fields I added value and onChange properties:
Now the Checkout’s state can be updated, we can also validate the field. To do so, after setState in the handleChange function I passed a second function to check the validation for the field.
This sets a property in the validation state for a field and adds an errorType with helper text. The fieldValidator is a function with a switch statement allowing you to handle the field appropriately. For most of the cases in this example, I have used that the value’s length is greater than 0. It also allows for more complex validation, which I did for the PaymentForm.
It also means the AddressForm’s fields can be updated with error and helperText:
This means each required field is validated and returns some guidance to resolve any issues if not valid. To validate the form as a whole and prevent progress through the steps until each is complete, I added the handleFormValidation function called after each field validation which uses the formValidator:
To prevent progress we can disable the Next step button with a simple check against the current step and it’s validity:
We can repeat these steps for the PaymentForm and along with adding some of the additional, more complex, validation elements such as validating the credit card number. In this demo I used Regex and a luhnCheck but you might want to use alternatives in reality.
Pulling these together, results in the Checkout validating each step and allowing progress when the required fields are completed and validated as per the PaymentForm below:
This was a demo using Fragments in React with a more complex process than the simpler examples. I’m not 100% sure about their use in this way, so I welcome any discussion about this. You can find the complete repository here and the demo here please .
Thanks for reading. If you liked the story please hit the “Follow” button or clapping. I’m going to start adding articles each week in which I hope to be exploring more features in various languages and adding further tutorials. Many Thanks.