Trying Out ReactJS

Posted on January 2, 2017 by Brian Jaress
Tags: code, demo, javascript, reactjs

To try out ReactJS, I wrote a little color app. It uses the tinycolor2 and color-space libraries to convert back and forth between RGB, CIELAB, and CIELUV. I haven’t checked browser compatibility 100% thoroughly, but most of you should be able to drag the sliders around, type in the text boxes, and see the color change. Check out the code if you’re interested. The rest of this post will be my thoughts on ReactJS.

Summary

ReactJS will get the job done, and it makes certain key things much easier. It also feels a lot like something written in-house at a big company. If The ReactJS Way makes total sense to you, go ahead and use it. If it feels cumbersome, remember that you are probably not a big company and might want to use something else.

Testing

When you use ReactJS, the framework is pervasive. It helps you split your code into pieces, at the cost of having parts of the framework mixed into every piece. You really have to use something like Enzyme to pretend to be the rest of the framework when you test components. I also used Jest because that came with the starter kit, but if I were to do another ReactJS project, I might switch to a different test framework. Personally, I’d use one of the JavaScript ports of Hamcrest and junk Jest if it didn’t work well with that.

Structure

In ReactJS, the main structure of your code is almost always going to be a tree of components. That’s just how ReactJS is designed.

Partial diagram of components in the color app

Partial diagram of components in the color app

It becomes awkward to define behavior outside the tree, unless it’s part of a separate data model (like color format conversions). That means things are components plugged into ReactJS with properties, render methods, and the component lifecycle, even if their purpose is really to specialize the behavior of other components.

Basing everything on composition worked fine, and extracting generic components was relatively painless. Putting JSX directly inside the render methods was also fine. The not-so-ideal part was needing render methods (and other ReactJS-specific code) everywhere, even if all they did was pass along properties.

Tradeoffs

If I hadn’t used ReactJS, figuring out how to structure the app would probably have been a bigger part of writing it. On the flip side, coaxing ReactJS to do what I want would have been a much smaller part (even though I chose a goal that seemed well-suited). I would probably end up with a smaller, simpler codebase because it would more closely match the problem space and my preferences.

For example, the default behavior in ReactJS, and the logical conclusion of how Facebook recommends using it, is that invalid user input is immediately clobbered. The user is pressing letters on their keyboard that cause text to flicker instead of to become longer.

It takes extra work to create the behavior that most people want, and that I assume most ReactJS apps actually provide: letting people edit their invalid input to make it valid. That’s important when invalid input can be a prefix of valid input. The color app I wrote can take any color string accepted by tinycolor2 in the topmost box, so “blue” is valid, but “blu” is not.

Tools

The create-react-app starter kit does what you’d expect and includes the whole build pipeline, which is nice. There are a few things missing, like Enzyme and immutability-helper. Maybe Facebook is leery of adding external (to Facebook) dependencies, so they’ll add links and recommendations to their online docs, but won’t add a line to their package.json.

Conclusion

ReactJS is actually a very corporate framework. It tries to reduce decision-making at the cost of a larger, more complicated code base, and it favors code organization based on feature slices over organization based on the problem domain. A big company like Facebook probably gets more advantages out of it than I do because they have a large in-house library of components and lots of people to write and maintain components.