It’s a bit annoying with searching the internet - every time you look for a framework or a library which is a little bit trendy, Google simply brings up posts by its advocates. They will tell you a lot of nice things about it. The same problem with React, a popular Javascript library - you will hardly learn what’s the problem with it, even if you enter “when not to use React” into the search engine. Yet, it’s simple, and written plainly in reactjs.org Design Principles: ”The key feature of React is composition of components. Components written by different people should work well together”. “Should”, right?
React is beautiful for writing applications, and is the second most popular framework in 2020. But here’s the catch - its components are by definition opaque and can present you with various pains when re-using them in different contexts. To understand why, this piece unpacks what component-based design is, and wouldn’t we be better off using good ol’multi-paradigm Javascript instead.
But first of all, what is React?
ReactJS, or simply React, is a JavaScript library that provides a set of methods for better handling of front-end behaviours. It was created by Facebook’s software engineer Jordan Walke in 2013 as a way of building a dynamic UI with high performance, which was achieved by mixing the client and server-side processing of data. This essentially allowed the web pages to quickly respond to user’s clicks on likes and chat messages, as in client-side processing, and simultaneously be SEO-friendly, as in server-side applications. This principle of mixed behaviours is called isomorphism - and here’s a good explanation of it. So far so good - React performs faster, it’s easy to learn for anyone who knows Javascript, and hides all the complex internal code behind its layer of abstraction, leaving you only with fun stuff. But, crucially, it’s also component-based, meaning that it ideally designed in a way that its bit and pieces could be re-used.
Object- vs Component-based systems
Javascript at the core of React is a multi-paradigm language, meaning that it allows for both functional and object-oriented styles of programming. Leaving the explanation of the difference between these two styles to the brilliant piece by Shaistha Fathima, what is important here is that React itself uses a component-based model, which is, in essence, an extension of object-oriented one.
How are objects different from components? Both come from the same core programming principle of evil duplication: do not duplicate knowledge throughout your systems (Thomas and Hunt, 2019:73). Based on this, software development has been steadily moving towards modularisation and had initially arrived, in the 1980s and 1990s, to the paradigm of object-oriented programming. Here the code would be build based on objects, their attributes that define their behaviour and methods that explain how objects relate to one another (SWEBOK, 2-10). The strategic advantages of building the code this way would ideally speed it up and make it easier to maintain because it will be better at interoperability (data exchange), will reuse the same object, meaning that it will scale easily, and be more reliable, as it will take less effort to test (González and Torres, 2005). With time the object-oriented model has evolved into a component-based, where components became more independent entities that could be developed and maintained separately. The idea was that the main application will use the component’s interface, using it similar to the object. The advantages over objects would be, for example, ability to call them from any language, and overall better quality.
The problem with components
Here’s where the paradox is - the system would work faster when it relies on the opaque components that encapsulate states and behaviours. But simultaneously, the system becomes harder to use, because the time and resources saved on writing the code are now spent on the activities that help make component model happen - we need to have more strict design and documentation, and a system of standards that allows to plug those components in. Remember all those phone chargers and cables you bought over the past ten years, now gathering dust in that murky place behind all the cardboard boxes? Components bear the same risks of becoming incompatible with new architectures. As Webflow’s Nick Gard observes, React components come with assumptions on how the application works and looks. And since, as we saw from the component-based strategy, they hide away all the markup, style, copy and behaviour, the components should be mostly worthless when trying to reuse them in the shape of a library.
Hooks as crutches?
Quite tellingly, the hooks that were introduced from React 16.8 back in 2018 are aimed at addressing these same problems. First, the ability of components to re-use the stateful logic. That’s the type of logic that is based on the states, which, in turn, are the values that describe the current condition of the component (Stackoverflow). Second, complex components become hard to understand. But now, what is “complex”? Something that you wrote two months ago, and now cannot recall what’s in there anymore? Or just something that has more than three lines of code? Then, safe to assume, it’s anything. Would that mean then that hooks were introduced as a cover-up for a larger strategic flaw, which is so vast it’s even bigger than React itself? Perhaps, this indicates a problem with the component-based design as a whole which was haunting it all along.
Conclusion
Admittedly, many other features that React shines at, such as virtual DOM and isomorphism we saw in the beginning, but these are the themes for a whole new blog post. And, after all, React is still indispensable for writing applications. All you need to survive your next React project is to be sure to write your own components and never plan to re-use them! But would the risks of component-based design finally sink it, together with other libraries that use this paradigm? Leave your comment, tweet the post or share to your favourite Facebook group to continue the conversation.
References
Bourque, Pierre, ed. 2014. SWEBOK (Software Engineering Body of Knowledge) Guide. IEEE Computer Society.
Brereton, P., and D. Budgen. 2000. “Component-Based Systems: A Classification of Issues.” Computer 33(11): 54–62.
González, Rafael, and Miguel Torres. 2005. “Critical Issues in Component-Based Development.”.
Thomas, David, and Andrew Hunt. 2019. The Pragmatic Programmer, 20th Anniversary Edition: Journey to Mastery. Second edition. Boston: Addison-Wesley.
Vitharana, Padmal. 2003. “Risks and Challenges of Component-Based Software Development.” Communications of the ACM 46(8): 67–72.