React-Redux Invoice SPA Prototype with Router & Flow

Wanting to level up with React, Redux, Flow and Router, I found Seed’s Frontend Homework assignment describing the basic frontend to an invoice web app — and thought it was a good problem to experiment with. Below is my linked solution, and commentary on my experience working with those technologies.

Repo on GitHub:

Commentary:

React. React seems to have emerged as the most popular JS framework to date, and has deep community support. I’ve enjoyed working with it, and it’s become my goto for front end.

For comparison, there are currently more React jobs on StackOverflow Jobs than other similar frameworks (not entirely apples to apples, but close enough): ‘reactjs’ (247), ‘angularjs’ (208), ‘backbone.js’ (18), ‘ember.js’ (16), ‘vue.js’ (8), ‘knockout’ (4). This writeup by Erik Bernhardsson also does analysis on current popularity on JS frameworks: “The eigenvector of “Why we moved from language X to language Y”

Redux. Neat and tidy pattern for managing a single application state/store —which when properly bound to React component states, creates some really powerful debugging and ‘time travel’ capabilities. Got to play a bit with Redux DevTools in Chrome, and they aren’t joking about it being a great developer experience.

Found a great write up on “Three Rules For Structuring (Redux) Applications” that I mostly followed. This repo has related structure: “TodoMVC example using Redux, React, and Typescript”. Something I’m noticing in followups to that blog post are things like Selectors and Filters that I’ll definitely apply next time around.

React Router. Router allows me to leverage urls patterns like ‘/’ ‘/new’ and ‘/edit/:id’ to represent pages. In order to get this to work properly on a single, static index.html file on GitHub Pages, I had to carefully make a few mods to my project as described on the Single Page Apps for GitHub Pages repo.

Create React App. Zero configuration makes prototyping projects like this so much easier to be productive on. Since I’m still relatively new to the React ecosystem, I’ve reaped the benefit of years of iteration on this problem. Sounds like this tool has been a boon, as I’ve read about how the requirements of Babel & Webpack for developing with React was more of a hurdle in the past. Overall nothing to complain about here — works as documented per my experience so far.

Flow. Having worked with ActionScript for years, it’s nice to have static typing developer features again (autocomplete, hints, author time errors). I debate digging into TypeScript or Flow first, but chose Flow since it’s a more integral part of the React ecosystem. Works much better when coupled with an editor like Nuclide or WebStorm vs. using the basic CLI output.

One frustration point — I struggled with how to connect to the Flow server running in my Docker Compose service. It’s probably possible, but after fumbling with the remote Nuclide server in the service, I couldn’t get it working, so gave up and just ran a local Nuclide/Flow instance on my local machine which worked fine.

Another pain point—some modules I wanted to use didn’t have flow types (enzyme-matchers), so my project started throwing errors based on that module’s imports. I dug around a bit on how to ignore those errors, but chose to spent my time elsewhere, and am instead watching a PR for the flow types to be added to that 3rd party package. Moving on for now.

This Flow type cheat sheet is handy, and I’ll try to installflow-typed on my next project (ran into some issues with docker here, their install isn’t quite trivial).

There are several side benefits of using Flow with React, like: PropTypes can be replaced with a component class props: field, can use defaultProp as a static class property, can assign types to state, and more.

Jest & Enzyme. Works as expected. Unit testing for React components & containers is nice and fast. Snapshots are super handy, and remove need for script testing a lot of mundane UI changes. There is still room for some end-to-end browser based testing like with Selenium Webdriver though. Once needed for a React solution like this, I’ll probably delve into Nightwatch.js.

Nuclide. Adding the Nuclide package supercharges Atom editor for FB ecosystem centric development. Coming from using WebStorm and RubyMine, I’m still getting used to the slightly different feature set and keybindings of Atom — but I really like how lightweight, and well designed it is. I only scratched the surface of what can be done in Nuclide. It was generally painless to get ESLint and Flow integrated errors, and Flow’s hinting working. Looking forward to getting more familiar with the feature set.

Styled Components. Coming from years of working with CSS and SCSS, I didn’t immediately understand why you’d want to put your styling back into the JS — as it sounded like inline styles which is like… a regression, no?

However, with React components, it starts to make sense as a way to remove/simplify the need of naming styles, allows you to keep the styles close to the components (or put them into their own file), use JS to manipulate the styles, create ‘mixins’, use themes, and use a quasi component style inheritance/modifiers with props. I’m new to this, and it’s still young, but I’m going to keep testing the waters.

This write up goes into much better detail: CSS Evolution: From CSS, SASS, BEM, CSS Modules to Styled Components

React-Bootstrap. Decent wrapper for basic bootstrap styles and components. However, one negative is that with react/enzyme tests can’t use ‘shallow’ renders if you are looking to interact with any of those bootstrap subcomponents in your tests. Had to switch over to using the deeper ‘mount’ render for those deeper interaction (or bypass boostrap-react and just use div and classNames for specific styles instead of the components — which sort of defeats the purpose of using the bootstrap wrapper).

Docker Compose. I’ve been trying to get in the habit of using Compose on all new projects to encapsulate the dev environment. Aside from the Flow/Nuclide issue above (which there is probably a solution to), it worked well here.

TravisCI => GitHub Pages. Each commit to the GitHub repo will trigger a build on Travis. On success, it will deploy the build to GitHub Pages. The build is created with create-react-app, which is super convenient. See the note above in Router for the edits needed to get it to work on GH Pages.

Having this CI pipeline setup gives me a level of confidence, and peace of mind, that when I push up simple edits (styles, text tweaks, anything low risk) — I can just return to working, and know the edits will either find their way up to production, or the build will gracefully fail without any real harm done.