Quick Tip: Reduce some common React boilerplate

If you’re keeping track of a presentational component’s visibility in state, then you normally need to set up an initial state in your constructor and set up click handlers to deal with toggling that visibility. But through the clever use of some ES2015 features, you can get rid of a lot of the overhead you need to construct this. Check out this example:

https://gist.github.com/timdorr/7210fc153e21d11b4792

Pretty neat! That knocked this example component’s size down to about half of the other one. We use the fact that the initial state is falsey if it hasn’t been set to read from a default object. We also use an inline arrow function to toggle the visibility state, rather than extracting it out to a full class method.

This won’t scale if you’re needing to read from state in multiple methods. Nor will it scale if you need your toggle button to do other things. However, for simple components, this can keep you from having to type out as much code as before, which reduces complexity and increases readability when you go to a code review.

Some Code Ideas

I’ve got a bunch of random ideas sitting around in the old mind palace around ways to improve the Javascript ecosystem and libraries. I figure I should get those out before I either forget them or my brain explodes. So, I present you with a wall of text that is hopefully somewhat useful.

A Different Router API

I’m a contributor on react-router, which is a Javascript library to build routes in React apps. Think “pages” in a single page app (SPA). It’s extremely powerful and handles a lot of things, such as asynchronous data loading and code splitting. It’s really, really good and you should check it out if you haven’t already.

However, I was thinking about a way to simplify its use for most users. Here’s a common pattern you’ll see when using it:

https://gist.github.com/timdorr/2a23ad0661626f46dfb3

This is just the routes isolated in their own file. It makes it easy to reason about the layout of your app’s pages. But it seems like a lot of typing to set up these special Route components that just link you over to your actual React components. What if we didn’t have to do that?

https://gist.github.com/timdorr/ce0ef31283771f52ddca

Neat! How do we do something like that? Instead of wrapping the component inside of a Route, the component is created as a router component explicitly:

https://gist.github.com/timdorr/7333cd9c5b470d384f43

Why would that be better? One of the more non-obvious features of react-router is that it passes lots of useful props to the Route components, such as this.props.params. However, the component has no guarantees that it’s being used in a route. Practically speaking, that isn’t going to be a problem because you’re in complete control of your code and it would be a weird pattern to expect route props and then not use that component in a route. However, being explicit about your code’s expectations are always a good thing.

In addition, you could potentially access things like params even when your component isn’t being used directly as a route. That information could be passed down via this.context and accessed by any child node under a route.

Of course, this doesn’t take into account more advanced use cases, such as asynchronous routes, but it could be an interesting pattern to explore for simple use cases.

Autoloading Javascript

I’ve written a lot of Rails code. I still do. Ruby is a great language for backend systems and Rails makes it exceedingly simple and terse to whip up a full-featured REST API in no time. I recently tried to do the same in Node and it was like pulling teeth. There was a lot of DIY setup and fiddling just to get things working. Gross. I know things like Adonis exist to make this better, so hopefully its popularity will grow over time.

But one fixable part of the problem was how much space was wasted on explicitly defining imports in every file. Look at the examples above and notice how nearly half the code is imports. This is something Rails solves with a fantastic autoloader so you never have to require a single file in Rails. It’s almost an anti-pattern if you do. Wouldn’t it be great if you could do that in Javascript too? So, the previous routes file might look like this:

https://gist.github.com/timdorr/104c1742310b72d4195d

A third of the code gone, but even better, we don’t have to edit the code in two places to add another route: once for the import, once for the route itself.

How would one implement something like this? One way might be a plugin to Babel to look up undefined variables and add in import statements to the code dynamically. You might also override on a per-path basis with a .autoload file, which would let the autoloader know to only search in our route components path. In a Redux combineReducers instance, it would have it autoload from the path to your reducer functions.

Webpack Preset

This last one is a little more self-serving. I’ve been (slowly) working on building out more of Webpack Preset. One of the things I don’t like about webpack (and why I always preferred Gulp to Grunt) is its use of a configuration object instead of a configuration API. (Even better, it could offer both!) So, most of my presets end up doing some funky object manipulation and have a lot of redundant code between them.

What I plan on building out in more detail is a configuration API to webpack. Jason Quense has already experimented with this a bit, and I will probably end up poaching bits of it (with credit, of course!). But my thoughts are to make this a separate library so anyone can use it.

One of the most complex parts of it will be allowing us to serialize the constructed config into a webpack.config.js file. How best should you convert a plugin back to a new webpack.optimize.OccurenceOrderPlugin() statement? I’m not 100% sure how, but it could be pretty interesting to find out!