Yanis Triandaphilov lives and works in Prague. He's been into Ruby and JavaScript development for more than six years now. "Being not too smart, I struggle for clarity and simplicity in everything I do."

Give Codeship’s CI/CD Platform a Try

Want to learn more?

Recently I decided to migrate one of my side projects to React. I had several reasons for that, but the most important is that, obviously, Angular 1 is old, and nobody cares about it anymore. No community, no bugfixes, no improvements. It is basically dead.

So I decided to give React a go. And you know what? I was blown away by how easy it was to rewrite my whole application from Angular 1 to React. It took just a couple of weekends, impressive given that my application is rather complex with several dozen related and interdependent components.

In this article, I’m going to share my impressions and will describe the transition I had to undergo to think in React.

Overview and Comparison

React is a small view library, but you still need to learn a lot to create a basic application.

Prepare to write more code, but bonus, it should be more straightforward.

More JavaScript-ish. Less mental overhead.

One-way data flow is verbose in practice, but more direct and easy to reason about.

JSX is not that bad. It’s more lintable, so it’s easier to spot errors.

You have to use classes for stateful components. But please don’t use inheritance.

In React, you always want to have less state to manage, so you should prefer function components to class components.

Ecosystem

Usually, people say that React is simple because it’s just a rendering library, which is true (one can easily walk through the entire documentation in several hours), but that doesn’t mean it’s easy to create a new project with it. And that’s because React itself is not sufficient for a complete application. You will need to learn things outside the React library but within the React ecosystem.

As soon as you start making React applications, your first questions will probably be:

How do I fetch the data?

How do I describe routes?

How do I manage state?

How do I interact with API?

There are of course multiple answers to all those questions. But you need to understand that React won’t answer them. Those are the decisions you’re going to have to make on your own.

Verboseness

After moving from Angular 1 to React, the next thing you’ll notice is that you have to write more code. In my experience, it’s around two times more typing. It’s frustrating, but after some time you get used to it. In general, there’s a tradeoff between verboseness and clarity — React is more verbose, but as an upside, the code is more readable.

In practice, however, I would say, it’s perfectly possible to write readable and maintainable Angular 1 code just as, vice versa, it’s possible to write terrible and convoluted React code. So I guess it boils down to your personal style.

React concepts that increase verboseness are JSX and one-way data flow, but we’ll talk more on those later.

React is more JavaScript-ish

Every time you learn a new framework, there’s an overhead of what you need to learn. Those are things that lie in your brain and make you productive within a particular framework but are useless when you switch to another thing. React is more down-to-earth than anything else I’ve used before. Whatever you do, just write JavaScript, even when you write templates. But more on this in the next part.

JSX

When people encounter JSX, they often complain about violation of separation concern. You write JavaScript code and HTML-like markup in the same file, and that scares people off. In reality, though, it’s not a violation if you put them in one file. It’s a violation when you mix up logic with a view, but that’s totally avoidable.

Constructions like if and for within your markup have nothing to do with separation of concerns.

We do the same thing in Angular with ng-if and ng-each. But in React, the code is not artificial — that’s just markup + JavaScript. Since it’s a superset of JavaScript, it’s perfectly lintable, so you will know you’re missing a method at the linting time. In the case of Angular, it will silently fail even at runtime (because templates in Angular are just strings).

This one was a game changer for me.

On the negative side of things, it’s good to understand that JSX is not exactly HTML + JavaScript. There’s still stuff that is React-specific; for example, you have to write all the properties in camel case, and you can’t use class. Instead, you have to write className.

Oh, and you also can’t use strings for styles. Instead you write something like this: style={{ marginTop: '5px' }}. All this means you can’t just take a piece of your HTML markup and use it as React template — you still need to adjust.

One-way data flow

Okay, moving forward to one of React’s key selling points: the data flow. In React, it always goes from the parent to children. What if a child component needs to update the state? In that case, it should communicate to its parent via a callback. The parent will update the state, and so the data will pass down to the child again, causing the rerender (the virtual one).

In practice, this does lead to a more understandable stream-lined data flow. As a downside, you again have to tolerate the mental overhead. Imagine you have a tree of components, and something changed at the very bottom of that tree. To propagate the change to the top components, you have to pass a callback all the way down through all the levels of the tree. It is cumbersome, but state managers like Mobx or Redux help to deal with that. However, they can add more overhead.

Classes

So I couldn’t avoid this aspect. I still think that classes are weird out-of-the-place creatures that shouldn’t have made it to JavaScript. I imagine they were introduced to make Java folks feel at home. Underneath, nothing changed — that’s still a good old prototype-based inheritance. class is just syntactic sugar that attempts to hide the nature of the JavaScript, and it fails to do that.

Class-based programming in JavaScript is complex, hard, and convoluted. As opposed to functional programming, that may be a bit wordy first, but in the end, it scales so much better. Even in React docs they warn against using inheritance with classes.

But well, whatever I say, you can’t change the fact that React API use classes. If you’re using a stateless component, you should use a pure function. Whereas if you have state, you need to use classes instead. And as a React developer, your job is to try to localize the state, which means using pure stateless components (functions) as much as possible and use clauses as little as possible.

Note that nasty user: '=' thing. That’s a two-way data-binding, meaning you can change it in the component and it will change in the parent as well, and vice versa. That’s something you can’t have in React.

Rewriting it in React turns out to be really easy; all you have to do is to create a pure function. That function accepts properties and returns a JSX markup that needs be rendered.

We had to utilize classes here. In React, every component that has state needs to be a class. It has a componentDidMount method, which is a lifecycle hook, and it’s being invoked after component rendered into the DOM.

Instead of ng-for, we’re now using a plain JavaScript to render a list, which is very nice.

Instead of directly setting state, we have to use setState method. Otherwise React will never know that the state has changed and it needs to rerender.

Propagating the state

Let’s have some fun now. Suppose that for every contact we have an editable field, say, a phone number. In Angular, we will use ng-model for that.

Nothing else is changed. Since we have a 2-way binding, when we change the phone, it automatically propagates to the parent array of users, and that’s it. With React though, we need to implement the propagation ourselves.

Subscribe via Email

Over 60,000 people from companies like Netflix, Apple, Spotify and O'Reilly are reading our articles. Subscribe to receive a weekly newsletter with articles around Continuous Integration, Docker, and software development best practices.

We promise that we won't spam you. You can unsubscribe any time.

Join the Discussion

Leave us some comments on what you think about this topic or if you like to add something.