Some More Thoughts on React

I’ve been immersed in React for about three weeks now, and so far I’m finding it really easy to organize and maintain. Compared to Angular 1 (still haven’t tried Angular 2), my code is also much easier to read and understand. I like how JSX lets me embed HTML-like syntax inside JavaScript, instead of having separate HTML templates with Angular’s unique syntax embedded within. With React, you don’t have to learn all that new syntax.

An all-JavaScript approach not only feels intuitive but it has performance benefits. React achieves this by decoupling state from the DOM and storing it in a virtual DOM. When state lives in the real DOM you must traverse a sometimes huge tree structure to update a node (think jQuery), whereas with React’s virtual DOM, it keeps an eye on the state of a component via a diff algorithm, and whenever it changes, it simply converts the component to a React element and inserts it in the DOM. Imagine a DOM with thousands of child nodes – the virtual DOM approach results in far greater efficiency.

Furthermore, the idea of designing a code base in terms of reusable UI components instead of a larger MVC framework vis-a-vis Angular 1, cuts down significantly on my code base. Its principles encourage me to think more about the features and layout of my site.

Most important, I love the React environment. With webpack and the webpack-dev-server, debugging is a synch because it happens in real time; the server watches your source files and recompiles them whenever there is a change. If there’s a bug, the app will break and almost always yield a helpful error message because React is all JavaScript. On the other hand, because Angular embeds its own syntax in HTML templates, debugging can be more difficult.

I also love the object-oriented approach that React encourages. With ES6 classes, I can define state and the events that change it in the constructor of my component. That makes the code more succinct and maintainable for a colleague who might jump in on a project. Here’s an example of an ES6 class with a constructor function from a current project I’m working on:

Lines 7-9 above demonstrate how quickly one can get up to speed on what this component is responsible for: keeping track of a username in the DOM. Line 7 signifies that the username property is what we are watching. Line 8 tells us that there is an event that updates that property while line 9 shows there is a form submission event. A fellow developer jumping into this code would be off to a great start synthesizing its purpose. On a side note, it’s important to note that we must call .bind and pass in this on both of our events; otherwise this will be undefined in the method.

Let’s talk about line 5 as well. All React classes are initialized with a props object via calling super(props). Don’t be sidetracked by the super part. The only effect of calling super on props is so you can access this in the constructor. It’s probably redundant because we already have reference to props but the React docs encourage it: “Class components should always call the base constructor with props,” which is in keeping with object-oriented JavaScript’s standard of binding instance properties to this.

The props object allows you to access anything you pass in while “invoking” a component. Because I’m using React Router, my props object contains all sorts of useful information like routes, route params, and location, plus anything else I want to pass when I invoke the component.

Let’s take a look at my routes and compare it with the props object it yields.

On line 11, I “invoke” a route component and pass it three key/value params: path=’playerOne’, header=’Player One’, and component={PromptContainer}. component points to the class where all this information is headed.

Now, inside the constructor of PromptContainer, let’s log the props object to the console. A lot of useful information lives in props when you use React Router, but lets focus on what we manually passed in. The route object contains all the info we passed in and we can now access by call any of the keys on this.props.route.


Finally, let’s demonstrate how we can use props, state, and the events defined in our constructor in the render method of our UI component:

On line 3, we access our header prop as the value of our tag. Line 5, binds the onSubmitUser event to the React onSubmit callback. Line 11 binds our onUpdateUser event to React’s onChange event (this watches for any changes to the input field). Last, on line 12 we set the initial value of the input field to the state of username defined in the constructor.

Check out this codepen to see a working example. Note that the app is incomplete. After you enter player two’s name, an alert will flash.