Using React and Tcomb’s Union Types to Build Better Conditional Forms



Cadre is rethinking decades-old practices in the real estate industry. Phone calls, paper documents, and a hike to the bank don’t keep you from investing in the stock market, and they shouldn’t keep you from investing in alternative assets, either.

So it’s only fitting that while moving a legal document signing process online, we were slowed down by a concept as old as the GUI itself: the form. Displaying a few simple inputs is easy, but wiring up several dozen, each with complex validation and conditional display logic? That’s when we outgrew even our well-encapsulated React components.

Of course, we’re not the first team to ask a lot of the humble

. There are dozens of libraries that purport to solve these problems, but most fall short. We eventually found tcomb-form, which uses runtime types to generate React forms on the fly. One year later, tcomb-form powers nearly every input on our site. We like it so much that we even released our own addition to the tcomb ecosystem: tcomb-builder, an immutable builder syntax for defining tcomb types and forms.

But despite our growing reliance on tcomb in the last year, it wasn’t until recently that we took advantage of one of its slickest features: conditionally displaying fields with the union type. It’s powerful, you need it, and here’s why.

Conditional Logic

As a motivating example, consider a form on the site that asks for the investor’s bank location (required by “Know Your Customer” regulations). The logic is simple: Show the city and state fields only if the selected country is “United States.” Otherwise, hide them.

How might this look in React? To oversimplify, something like this:

Even while coding up this dummy example, a few thoughts came to mind: How do I validate both layouts? How do I store and update my switch, isUSA? When I build a similar page, can I reuse my solutions to the prior two problems?

In response to these questions and more, tcomb-form has a single, emphatic reply: Use a type system! In this particular case, the union-options>union type.

The bank location form has two possible layouts. Let’s call them international and us (as in United States). Both have a country input; us also has city and state. In tcomb, these two options, us and international, are defined as types.

The international type only has a country field, shown here using tcomb-builder syntaxM.

CountriesBuilder—imported from elsewhere—is an enum of countries (the data model) rendered as a dropdown (the view).

Every tcomb-builder is immutable, so every .set method returns a new builder. Here, the us type is defined as the international type with additional fields for city and state.

Just like CountriesBuilder, UnitedStatesBuilder is an enum of states rendered as a dropdown.

Finally, the union type is either the international type or the us type. How does the union know which is which? We tell it with the dispatch function, below defined to return the us type if the selected country is the United States (‘US’) and the international type otherwise.

All the hard parts ,  from showing and hiding the actual React components to calling validation functions associated with each form , are handled by tcomb-form.

Here’s all of the code together:

To render the form, just use tcomb-form’s component.

Other Applications

Here are a some other ways we use union types on our site:
Fast follow questions

An address that can be the same as a previous one

Wrapping Up

It’s readily apparent that the tcomb ecosystem  ( tcomb, tcomb-validation, and tcomb-form )  is well designed from its basic building blocks (runtime types) to its user-facing conclusions (e.g. conditional forms). Using a union type to drive a conditional form is just one example of the many good ideas in these libraries.

This firm foundation is also what makes tcomb-builder, our immutable builder syntax for tcomb, possible. While the syntax in these examples comes from tcomb-builder, vanilla tcomb and tcomb-form could have been used instead. Our team just found that using immutable builders results in more maintainable code than vanilla tcomb-form’s mutable JSON blobs. Ultimately, everything “compiles” (in the simplest sense of the word) to tcomb and React.

And that, in the end, is its magic. Tcomb asks you to buy theory rather than configuration. It gives you building blocks rather than prefabricated components. How you use it and what you build is up to you.

Cadre is building the world’s first digital stock market for alternative assets. Interested in joining our team and solving challenges like these? Check out our Careers site.

Important Disclaimer

The views expressed above are presented only for informational and educational purposes and are not necessarily the views of Cadre or any of its affiliates. Cadre makes no representations, express or implied, regarding the accuracy or completeness of this information, and the reader accepts all risks in relying on the above information for any purpose whatsoever. This post is not intended to provide, and should not be relied upon for investment, accounting, legal or tax advice. Additionally, this post is not an offer to sell or the solicitation of an offer to buy any securities or other instruments.

Software Engineer at Cadre


Click on a tab to select how you'd like to leave your comment

Leave a Comment

Your email address will not be published. Required fields are marked *

Skip to toolbar