JSReactJS6 Tradeoffs for ReactJS

6 Tradeoffs for ReactJS

I enjoy React, but I have to admit, I gave you a one‑sided sales pitch. So in this article, let me step back and be more balanced. Here is the plan. Let’s consider six key tradeoffs that you accept when you choose React. These are the key tradeoffs that the React development team made when designing React. In the next few clips, let’s consider the impact of these key tradeoffs so that you can better understand if React makes sense for your team.

react

Tradeoff 1: Framework vs. Library

The first tradeoff is framework versus library. Competitors like Angular and Ember are frameworks. React, in contrast, is generally considered a library since it’s lean and focused on components. Now a framework isn’t better than a library. It’s a tradeoff. Here’s a few advantages to choosing the framework approach.

react

A framework contains more opinions, so you can avoid spending time trying to choose between many options. This reduces decision fatigue, and there’s often less setup overhead. Frameworks can help enforce consistency since most frameworks are more opinionated. But, React’s Library approach also has some clear advantages. At only around 35K Gzipped, React is smaller than most frameworks.

This means that it’s small enough that you can sprinkle it on existing applications so that you can slowly migrate an existing app to React, even a server‑side rendered app. Imagine you have an existing app built in .NET, Java, Ruby, PHP, Python, whatever. Since React is small and flexible, you can replace a single component on the page with a React component.

react

So you can use your React components anywhere because they’re lightweight. This is precisely how Facebook slowly migrated from a server‑side rendered PHP application to React. And React doesn’t force many decisions on you. It allows you to only pull in the features that you need to keep your app lean and fast. You’re free to pick the precise technologies that you need for your project, and you’re free to select the best technology for your use case as well.

Decision fatigue is also largely a solved problem with React because opinionated boiler plates, like create‑react‑app, effectively turn React into an optional framework. Now since React is a focused component library, more comprehensive frameworks like Angular come bundled with more features, including testing, a library for HTTP calls, routing, and internationalization all built in. In contrast with React, you select the pieces that apply to your use case and you add them in.

Since React is very popular, there’s almost certainly a mature library that does what you need. Here’s just a few of the most popular options for each use case. And the nice thing with React is your users don’t have to waste time downloading and parsing features that they don’t use. You can pull in only what you need from this list.

Tradeoff 2: Concise vs. Explicit

The second trade‑off to consider is concise versus explicit. React trades conciseness for predictability and explicitness. You spend a little more time explicitly wiring things up together, but that helps them not fall apart. And it also helps people better understand what the code is doing.

Here’s a concrete example. Frameworks like Knockout and Angular popularized two‑way binding as a way to avoid typing by automatically keeping form inputs in sync with the underlying data. This approach was extremely popular until React came along. It was popular because it requires less coding. With two‑way binding, JavaScript values and inputs are automatically kept in sync. In contrast, React embraces one‑way binding instead.

It requires a little more code. With React, you declare an explicit change handler, and you reference it on your input. This extra work has some benefits. You have more control because you can declare precisely what should happen on every event. This means you can transform and validate input before updating state and perform performance optimizations as desired.

Your code is more explicit since you clearly state what you want to happen when an event occurs. And this makes it easy to understand and debug when an error happens. Although React helped repopularize doing one‑way binding, other popular libraries like Angular have shifted gears and embrace it as well today for these reasons. Now, if your team strongly prefers two‑way binding, you can use libraries that add it to React, but for the reasons I just mentioned, few do so, and I don’t recommend it. Also, don’t worry.

You don’t need to declare a separate change handler for each input. There are simple patterns for centralizing your change handlers in React, as I show in my other React courses. So in the real world, the amount of code that you write in React isn’t substantially larger because of one‑way binding because you typically have a single change handler for an entire form. In summary, here’s the trade‑off. React requires more typing to implement than traditional two‑way binding approaches, but with the benefit of easier maintenance, greater clarity, reliability, and performance.

Tradeoff 3: Template-centric vs JavaScript-centric

The third trade‑off is template‑centric versus JavaScript‑centric. In a previous article, I contrasted the template‑centric approach of traditional frameworks with React’s JavaScript‑centric approach. Angular, Vue, and Ember seek to make HTML more powerful by inventing their own unique syntax for writing code in HTML. React takes the exact opposite approach and instead utilizes the power of JavaScript to handle HTML.

This fundamental difference is what makes React so elegant. Let’s consider simple if logic for conditionally showing an h1 tag when a Boolean called isAdmin is true. Here I’m using Angular’s unique ngIf directive, which must be prefixed with an asterisk. My conditional is written inside a string. With Vue, I use v‑if and again declare my conditional inside of a string. Ember also uses a unique syntax that looks a bit like JavaScript, but with no parentheses, and the entire statement must be wrapped in double curly braces.

With React, I can use JavaScript’s logical and operator. If you’re not familiar with it, the right‑hand side only runs when the left‑hand side is true. So, Hi Admin will only display when isAdmin is true. And since the code I’m writing inside the curly braces is ultimately just JavaScript in a JS file, any editor will provide autocomplete support along the way as I type and reference my functions. If I make a typo, I’ll see warnings in my editor if I reference a variable that doesn’t exist.

Now let’s consider writing a loop in each technology. With Angular, you say *ngFor, then use a syntax that looks a bit like JS, but is declared inside a string. Vue is similar, but a little less typing. Again, you write your looping code inside a string. With Ember, you use Ember’s #each helper, which is rather wordy compared to the others above. Finally, with React, you use JavaScript’s built‑in map function and a plain JavaScript arrow function to display each username. So the only React‑specific syntax is the curly braces around user.name. So it’s not just preferable because it’s less code.

It’s preferable because the syntax is plain JavaScript. Finally, let’s see how each handles clicking on a button. With Angular, you had parentheses around the event, and unlike traditional event handlers, you also put parentheses by the event handler name as though you’re invoking it. This syntax wouldn’t work if it were real JavaScript. With Vue, you use v‑on with a colon and the event name, or you can put an at sign at the front of click.

Again, both of these are Vue‑specific syntax. Finally, with Ember, you specify a plain onclick, which is nice, but inside you use an Ember‑specific convention to tie the click to a specific action, which is declared via a string. Finally, with React, you declare an onClick handler. So, in React, you use the native click handler name, but it’s CamelCased since React’s JSX uses JavaScript casing rules. Otherwise, the only unique syntax is that you specify the function name inside a curly brace instead of in quotes.

Place these together, and you can see the contrast. If you know JavaScript, then you know how to handle conditionals, looping, and events in React. This is why React’s API is so small. So after seeing the comparisons, let’s contrast the benefits of each approach. The benefit of the template approach is that it requires less JavaScript knowledge. Template languages provide a streamlined API for performing core functions.

You focus on enhancing a template with framework‑specific syntax. And these unique syntaxes have some advantages, like avoiding the confusion that’s often caused by JavaScripts this keyword behavior. This makes templates more approachable for developers who are new to JavaScript. And in theory, a template language is preferable because of a principle called the rule of least power. It’s counterintuitive, but less powerful languages can theoretically be preferable because they can protect from misuse by only allowing the user to perform a small set of prescribed operations.

For example, Angular’s template syntax only supports a selected subset of JavaScript‑like expressions. This helps avoid misuse. Of course, there’s an obvious downside that we just saw, which is that the template‑centric approach leads to framework‑specific syntax. To get good at template‑centric libraries like Angular and Vue, you must spend your time learning their specific syntax and rules for doing things that JavaScript can already handle. In contrast, React has very little unique syntax to learn.

And since React embraces JavaScript, you don’t have to learn a new vocabulary to describe the new features that other template‑centric libraries like Angular add to HTML. Most of what you write in React is really just plain JavaScript. This leads to less typing and less code, which I find produces a result that’s easier to read and debug. Finally, React’s JavaScript‑centric approach encourages improving your JavaScript skills. The list of features added to JavaScript in the last few years is significant.

If your team isn’t yet up to speed on the latest JavaScript features, it can take a while to get comfortable with all of this. But the great news is, once you do, you won’t just be better at React, you’ll be better at JavaScript forever more. In summary, to get better at React, you mostly need to learn modern JavaScript, and this is great because it means your skills will transfer to all other JavaScript code that you write, even if you move away from React in the future.

Tradeoff 4: Separate vs. Single File

The fourth trade‑off is a separate template versus a single file per component. Patterns like MVC popularized separating the model, view, and controller into three separate files. Traditionally, for web apps, this means that the view is HTML. The model declares the data for the view in JavaScript, and the controller controls the interactions with the model.

In contrast, with React, each component is an autonomous concern. Each component stands on its own and can be composed with other components to build rich, complex UIs. This means markup and logic are colocated in the same file. When React was introduced in 2013, people were very skeptical, and for good reason. React’s design ran against the current best practice of placing HTML templates and JavaScript logic in separate files.

In React, each component contains both logic and markup in the same file, so on the surface, this feels like it violates the principle of separation of concerns. However, in React, you think about separation of concerns differently. Traditional separation of concerns often fixates on placing each technology in a separate file. So in web development, this means placing HTML, CSS, and JS in separate files.

But React recognizes that while these are indeed separate technologies, they must be carefully composed together to do anything useful. So in React, each component is a separate concern. Examples include a button, a date picker, an accordion, or a text input. Each of these components is a separate concern. It will often embed logic, styling, and markup concerns because JavaScript, CSS, and JSX work together to create a useful component.

In my experience, placing such intertwined concerns in separate files actually hinders debugging and slows feedback because you have to mentally keep these separate files in sync. And, of course, by composing small, simple components together, you can create more complex components like contact forms, customer details, and so on. In my experience, components are the common concern worth separating. The old mindset of separating HTML, JavaScript, and CSS into separate files merely separated technologies, but their concerns and interactions are actually fundamentally intertwined.

If you change one file, it often requires corresponding changes to other files. Oh, and you’re not forced to handle styling in the same file. With React, you’re free to handle CSS in a traditional separate CSS file, if you prefer. Think of component composition like Russian dolls. Russian dolls are interesting because each doll can hold a smaller doll inside. React’s component model works the same way.

Simple, reusable components can be composed together to build rich, complex user interfaces. With React, you can think of the page as a set of nested components. Consider an author page on pluralsight.com. We could build this page in React by creating simple components like a star rating, an author photo, a navigation link, and so on.

Then we could compose those simple components together to make the course summary, the author summary, or the sidebar navigation. Finally, we could compose those larger components together to create even larger components like author courses.

When you see all this displayed at the same time, you can see how the small components in orange are used as part of the larger components in blue, and the larger components in blue, like the course summary, are composed together to create large portions of the app in green, like the author courses. As you can see, React’s component approach lends itself well to building complex Uis by breaking your page down into small, autonomous pieces that you can reason about and test in isolation.

Tradeoff 5: Standard vs. Non-standard

The fifth tradeoff is standard versus non‑standard. React is just one of many non‑standard component libraries, but the web component standard has actually been around for years without much usage yet. So why aren’t many people building apps with standardized web components yet? Well, first, let’s review what the web component standard is.

The web component standard exists of four core technologies, templates which contained markup, custom elements, which allow you to expand HTML with your own custom elements, the shadow DOM, which encapsulates styling to avoid your styles leaking outside of your component, and imports, which bundle everything together into a single line that you can import onto the page.

I published HTML5 Web Component Fundamentals in 2015, and I remain hopeful about standardized HTML components. But unfortunately, the standard has yet to be embraced much by the development community. Today, most developers continue to use libraries like Angular, Vue, and React instead. So the big question is, why hasn’t the web component standard taken off yet?

Well, likely the biggest reason that people aren’t using plain web components is browser support remains spotty. The template tag isn’t supported in any versions of Internet Explorer, HTML imports are only supported in Chrome, Opera, and Android, custom elements are only supported in Chrome, Opera, and some of the newest Android browsers, and it’s pretty much the same sad story with the shadow DOM.

After years of waiting, it’s become clear that browser vendors have shown little interest in implementing the full suite of HTML5 web component features. So you need to add polyfills to make it all work cross‑browser. And once you’re pulling in extra JavaScript, you have to ask why you’re choosing an unpopular and poorly supported standard like web components instead of an extremely popular technology like React.

Second, web components no longer enable anything new. Everything that you can do in web components can be accomplished today in a cross‑browser friendly way using a variety of modern JavaScript libraries, including React. Let’s consider the core features of the web component standard and contrast them with React. Web components have templates for holding your markup, and in React, you use JSX to declare your markup along with plain JavaScript.

Web components allow you to expand HTML by declaring custom elements. React components accomplished that same thing. The shadow DOM lets you encapsulate your styles within your web component. Various technologies, like CSS modules, CSS in JS, and even React’s built‑in inline styles, assure that your styles are encapsulated automatically. Finally, web components offer HTML imports for bundling the component together into a single import.

With React, each component is a single file, so you can always import it via a single line import. So in summary, web components enable nothing new compared to React today. The third reason web components aren’t taking off is JavaScript libraries like React, Angular, and Vue offer compelling component stories that continue to improve. It’s both difficult and unlikely for standards bodies to be able to keep up with the pace of JavaScript innovation. Today, modern libraries offer a number of compelling features for binding, bundling, packing, and testing JavaScript‑based components.

Finally, since web components utilize standards built into a web browser, you can’t use them elsewhere like on native mobile. React in contrast works on mobile and virtual reality too, as well as a number of other interesting platforms. In summary, the web component standard may take off at some point, but currently the majority of developers continue to reach for the tools on the right because they’re innovating more quickly, offer a strong user experience, and run reliably cross‑browser today.

Tradeoff 6: Community vs. Corporate

The final trade‑off we’ll consider is community versus corporate backing. Many popular open source JavaScript projects are community driven. React is an open source project, but it’s backed and actively maintained by Facebook. This means that React is driven by Facebook’s needs. So if your apps are very different from what Facebook is building, React may not be ideal for your use case. But as I alluded to earlier, React’s corporate backing has some clear benefits.

Facebook provides React a full‑time development staff that carefully plans releases, writes documentation and blog posts, and provides ongoing support for issues on GitHub and often even on social media. Even though React has a full‑time staff, there are over 1,000 contributors to React, so the community is vibrant and engaged. Facebook is currently wildly successful. At the time of this recording, it’s the fifth most valuable company in the world, with a market capitalization of $445 billion.

Even if Facebook were no longer involved in React, the project would certainly live on without full‑time Facebook involvement for the foreseeable future. Plus, many competitors lack the benefit of a full‑time corporate development staff that React boasts today. So while React’s corporate tie is a potential concern, it’s also a significant benefit for support and ongoing development for the foreseeable future. Finally, as I mentioned earlier, Facebook is deeply invested in React with over 50,000 components in production. So as long as Facebook is around, they’re likely to continue providing significant ongoing React support. And that’s it. Those are the trade‑offs to consider with React. Let’s close out this module with short summary.

Summary

In this module, we looked at six tradeoffs to consider with React. Frameworks offer more opinion and standardization, but React’s library approach allows you to select only the tools that you need and pick the best tools for your use case. Other frameworks strive to be concise, using techniques like two‑way binding and abstractions over JavaScript operations.

But React is explicit, so code is more readable and scalable at the admitted expense of doing a little more typing on the keyboard. React chooses to be JavaScript‑centric instead of template‑centric. React’s JavaScript‑centric approach is easier to understand and debug and requires learning less unique syntax, but at the cost of requiring modern JavaScript knowledge. Many frameworks utilize a separate template file.

In contrast, each React component is a single autonomous file that you can work with and test in isolation. The web component standard has been around for years, yet it continues to lack broad adoption. Non‑standard approaches, like React and Angular, remain more popular because they offer the same power, more rapid innovation, and a superior developer experience.

And React is corporate‑backed, which means its design is influenced by Facebook’s needs. But Facebook continues to accept input from the community and has evolved React into a highly flexible and well‑supported system. Of course, with tradeoffs, there’s no right answer. But at least now you understand what you’re getting and what you’re giving up with each of these tradeoffs. In the next module, I’ll be even more critical. Let’s explore the common concerns that I hear about with React so that you can decide if the downsides that other people talk about matter to you.

Subscribe Today

GET EXCLUSIVE FULL ACCESS TO PREMIUM CONTENT

Get unlimited access to our EXCLUSIVE Content and our archive of subscriber stories.

Exclusive content

Latest article

More article