Key Takeaways ReactJS components are difficult to reuse in complex interactive web projects.

ReactJS’s Virtual DOM algorithm is time-consuming and imprecise.

ReactJS’s HTML templates are neither complete nor powerful.

ReactJS requires complicated asynchronous programming while communicating with the server.

Binding.scala has less concepts but more features. The promising Binding.scala solves complicated issues that ReactJS cannot.

(Editor’s note: This five-part series was originally published in Chinese on the Chinese edition of Insights and on InfoQ China.)

It is well-known that React is a great tool for implementing simple interactive websites, but how does it apply on complex interactive front-end projects? Does it function as well as it did in simple interactive websites?

In this article, I will introduce several problems that I encountered using React during program development and why I decided to develop a new framework in Scala to compare with React. Surprisingly, the amount of code was approximately 1000 lines, while there were roughly 30,000 lines in React.

Background

Related Sponsored Content

Last April, I first came across React on a client project. Compared to AngularJS, a framework that I had used before, the React framework was more accessible, convenient and useful.

Responsive data-binding is one of the most useful features of the React framework. It maps the sources of upstream data to elements on webpages, which provide a handy way to implement simple interactive websites.

However, after a few weeks, as I became more skilled in React, I noticed a serious problem: React could not solve tangled problems as conveniently as simple ones.

Next, I experimented with an application called TodoMVC. The graph below shows the TodoMVC app using my framework.

The framework I am using is called Binding.scala. It turned out that the app using my framework only had 154 lines of code, but using the React framework, it had 488 lines of code.

In the following sections, I will explain four issues in React and how Binding.scala resolves these issues.

Issue 1: React components are difficult to reuse in complex interactive web projects.

The minimal reusable unit in React framework is React.Component. It is more lightweight than Controller and View in the AngularJS framework. That allows web developers to exclusively provide one render function, which maps props and state to HTML elements.

Such a lightweight component is very handy in rendering plain and static webpages. Nonetheless, when there are interactions between one component and another, passing callback functions as parameters are inevitable. Particularly for webpages with complicated structures, we have to nest dozens of components from the inside-out, where those callback functions are passed through from parent to child components across layers and layers. The only outcome for applying React framework in complex interactive web projects is that the codebase would become too messy to maintain.

In More than React II: Does React.Component damage the reusability of React?, I will compare native DHTML API, React and Binding.scala for designing a reusable and interactive webpage and address how to straightforwardly implement a reusable and convoluted interactive logic using Binding.scala.

Issue 2: React’s Virtual DOM algorithm is time-consuming and imprecise.

The web page rendering algorithm of React framework is a virtual DOM differentiation algorithm.

Developers are required to provide render functions that create virtual DOMs according to props and state, and React will construct real DOMs based on the virtual DOMs given by render functions.

React will call render functions again and then create new virtual DOMs if there is a change in state. Next, it will analyze the differences between the updated version and the old version of virtual DOMs and apply it into the real DOM.

There are two weaknesses during the process:

No matter what is changed in-state, render functions will always generate new and complete virtual DOMs. If the render function is extremely perplexing, precious computational resources are wasted. It is time-consuming and imprecise for the React framework to compare two versions of DOMs. For instance, if you wanted to insert <li> on the top of a <ul> form, then the React framework would misjudge that you modified all components of <ul> and appended <li> at the end.

Since the two versions of virtual DOMs are mutually independent, the React framework has no idea about what is going on in data sources, randomly guessing processing operations depending on just these two DOMs. This kind of algorithm is extremely slow and inaccurate. Web developers would need to provide a key attribute, shouldComponentUpdate method, or componentWillUpdate method to help the React framework to guess right.

In More than React III: Is virtual DOM dead?, I will compare render functions in React, AngularJS and Binding.scala frameworks and then introduce an accurate data-binding mechanism that is straightforward and high-performance in Binding.scala.

Issue 3: React’s HTML templates are neither complete nor powerful.

React supports JSX to develop HTML templates.

Theoretically, front-end engineers can change static HTML models into dynamic web pages as long as they copy these static HTML models into JSX source files and add some variable substitution codes. Indeed, React is the most suitable option to reuse the given HTML templates compared to other frameworks such as Cycle.js, Widow and ScalaTags.

However, React’’s support for HTML is incomplete. Developers have to manually replace class and for attributes with classname and htmlFor. Furthermore, they also need to change inline styles from the CSS syntax to JSON syntax, which enables the eligible code functions. Though web engineers can copy and paste HTML models into codes, it still requires a lot of time and efforts to actually implement and then successively run the program. In this way, React is not superior compared to Cycle.js, widok or ScalaTags.

In addition, React provides propTypes mechanism to check the validity of virtual DOMs. Yet this mechanism is full of holes. Even if we specify a propType, React can only find errors while running the program but fail to find them in compilation.

propType also cannot locate naming errors. For example, if you spelled onclick instead of onClick, React would report no errors and the program would crash as well. In this case, developers would typically spend a lot of time and energy looking for such a meaningless error.

In More than React IV: How to statically compile HTML?, I will introduce how Binding.scala statically checks both syntax errors and semantic errors while completely supporting XHTML syntax and I will compare HTML models using React and Binding.scala framework.

Issue 4: React requires complicated asynchronous programming while communicating with the server.

MVVM, also known as Model-View-ViewModel, is a framework where React loads data from the server. Web engineers need to develop an access services layer as Model and treat state in React as ViewModel and render as View. Model is in charge of accessing the Backend API and setting data to state (aka. ViewModel) via implementing Promise and fetch API. Then render (aka. View) is responsible to render ViewModel on webpages.

During this process, the front-end programmers need to develop an asynchronous procedure that is consisted of massive closures. In this way, setting and accessing codes are in chaos and bugs come up endlessly. Even if we deal with all sorts of asynchronous events as meticulously as possible, the program would become incredibly complicated, which makes the program hard to debug and maintain.

In More than React, Part Five: Is asynchronous programming an awful programming model?, I will introduce how Binding.scala automatically synchronises the data from the server and prevents manually asynchronous programming and also compare the synchronization of data model using React and Binding.scala.

Conclusion

Though Binding.scala somewhat looks like React, the mechanism hidden behind it is easier and more universal, which is completely different from React and Widok.

Apparently, Binding.scala is more flexible and powerful. We can use Binding.scala to solve complicated issues that React cannot.

For example, besides the four facets above, the state management problem of React is non-negligible. If we introduce a third-party library such as Redux to deal with the state, the framework would become tangled and the number of layers would increase.

By contrast, Binding.scala describes a complex state using the same data-binding mechanism, the same as rendering a web page. And it does not need to introduce a third-party library to provide features like client-server communication, state management, and URL dispatching.

Differences between Binding.scala and React:

Binding.scala React Reusability Minimal Reusable Units Method Component Difficulty Levels of Reusability Can be reused no matter in either interactive or static components Easy to reuse in static components but hard to use in interactive components Webpage Render Algorithm Algorithm Precise data-binding Virtual DOM Productivity High Low Correctiveness Automatically ensures correctiveness Needs to be manually setup by developers keyattributes, otherwise the complicated webpages will become a mess HTML Models Syntax Scala XML literals JSX Does it support HTML or XHTML syntax Completely supports XHTML Partially supports, normal XHTML cannot compile.Developers must manually replace classand for attribute with className and htmlFor，what’s more, change style style from CSS syntax to JSON syntax How to check the syntax of the model Checks while automatically compiling Runs through `propTypes` but cannot locate obvious spelling errors Server Communication Mechanism Automatic Remote Data-binding MVVM + Asynchronous Programming Difficulty Levels of Implementation Easy Hard Others How to dispatch URL Supports URLs as normal binding variables, do not need third-party library Doesn’t support, need third-party library react-router Completeness of Functionality Complete font-end developing solutions Only contains partial functions such as View. Also requires third-party library to implement complete front-end program Learning Curve API is relatively simple，and it is easy for those people who have never used Scala to understand Handy. But it is extremely hard to study the third-party library which is used to compensate the weaknesses of the framework Binding.scala React

Two months ago, when I released Binding.scala in the Scala.js community, the most popular responsive front-end programming framework is Widok. Tim Nieradzik is the author of Widoc. Once he saw my framework, he could not help himself to compliment that it is the most promising HTML5 rendering framework.

Yes, he is right. Two months later, Binding.scala is now the most popular responsive front-end programming framework in Scala.js community.

Awesome Scala compares my framework with other counterparts also and it concludes that the activity and popularity of Binding.scala is incredibly higher than any other frameworks such as Udash and Widok.

In my recent projects, I gradually gave up using JavaScript and React but used Scala.js and Binding.scala instead. Because of Binding.scala, the future of front-end techniques has never been so bright and promising.

External Links

Acknowledgement

My sincere thanks to my reviewers: Kaifeng Zhang, Peizhen Zheng, Jie Zhang, and Ting Han. This article has been improved by the extremely valuable suggestions from the fine individuals I am proud to work with. And I also want to thank Jingyu Zhou for helping with the translation.

About the Author

Yang Bo is a ten-year working experience developer and works at ThoughtWorks China as a Lead Consultant now. He's an active open-source contributor in Scala, ActionScript, and Haxe community.