
Why You Shouldn’t Use ReactJS for Complex Projects - sjrd
https://www.infoq.com/articles/more-than-react-part-i
======
JamesMcMinn
I don't think the author of this article really understands what React is and
what it is not. They repeat several times that React is a framework - it is
not. React is a library, one which you can use to render components and build
interfaces. It doesn't claim to be a Framework for handling data, and making
comparisons between the number of lines required to write tiny TODO
applications isn't exactly convincing when the argument is that you shouldn't
use React for complex projects.

The author writes off solutions such as Redux which are designed to solve
nearly all of the "problems" the author assigns to React because they add
extra layers to the application, however in reality, separating your data and
your views is EXACTLY the point - that's what helps to make complex
applications manageable.

The article is really an advertisement for the authors own framework
Binding.scala, rather than a critical look at React.

~~~
wvenable
If you have to architect your project around the use of this "library" then it
smells a lot more like a framework.

~~~
JamesMcMinn
You don't architecture you project around React - you simply fit react in
wherever you want to render the UI. React has a very small API, most of which
are simple lifecycle methods for dealing with changes in the state of a
component [1].

You tell React that you'd like to Render component X inside DOM element Y, and
that's really all React does. There's no architecturing your project around
React.

[1] [https://facebook.github.io/react/docs/react-
component.html](https://facebook.github.io/react/docs/react-component.html)

~~~
yangbo
Even though, the number of React's API is still larger than [Binding.scala's
API]([https://static.javadoc.io/com.thoughtworks.binding/binding_2...](https://static.javadoc.io/com.thoughtworks.binding/binding_2.11/10.0.2/com/thoughtworks/binding/Binding.html)).

------
acemarke
Most of this article seems to be complaints about using Javascript, a
dynamically-typed and interpreted language, vs using a statically typed
compiled language like Scala. The author also seems to dislike the idea of
client-side logic and data fetching, as opposed to server-driven.

A number of the comments about React are very overstated or overblown. For
example:

> 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.

In reality, unless the component tree is dramatically changed (such as
changing to an entirely different screen), the new VDOM contents are likely to
be almost identical to the previous contents. React makes a number of educated
assumptions about the structure of a VDOM tree to efficiently diff the
changes. That does take processing time, but saying it is "slow and
inaccurate" is just silly.

Ultimately, this article seems to be mostly about bashing React and trying to
sell the author's Scala HTML bindings library instead.

------
wereHamster
> The minimal reusable unit in React framework is React.Component

Wrong. And if you think the correct answer is "function" then you are wrong as
well. The answer is: an Element. A pure, immutable value representing a React
element. Example: const myReusableDiv = <div />;

> Developers have to manually replace class and for attributes with className
> and htmlFor.

So? It's just syntax. You can teach that, along value interpolation and
everything that a designer might need to be able to make changes to templates,
in less than five minutes to someone who only knows HTML.

> [talking about propTypes]. Yet this mechanism is full of holes.

So is JavaScript. Nothing to do with React. Scala is better, obviously. Any
statically typed language is better at that. And there even are languages
which are better at that than Scala.

If you are all like 'lol JS has no types, look at my fancy Scala code' then
I'll smack you with my Haskell ADTs. And then somebody from the Agda or Idris
camp joins and gives you a taste of dependent types.

> [how async programming is bad]

Nothing to do with React. React is just for rendering the UI. How you manage
the data is entirely up to you.

~~~
rickhanlonii
To be fair <div /> is a function when converted from jsx to js

~~~
wereHamster
<div /> is a constant. It's syntactic sugar for React.createElement("div"),
which is at runtime represented as an object {type:'div', ...} and a few other
fields.

typeof <div /> === "object"

~~~
rickhanlonii
I misspoke, yes it's a function _call_ to React.createElement

------
pedalpete
I'm a bit surprised to see this on a site such as infoq, and being written by
a developer from Thoughtworks.

If you have a 'complex project' you are going to need more than just ReactJS.
It's like saying Handlebars templating is no good for large projects.

The reusability of components in a large project, and specifically the issues
the author points out about interactivity between components, isn't supposed
to be done in react, you're supposed to have a data (store) layer which
manages the state of your components. This means the component itself is
essentially just an template for your output.

~~~
riledhel
I keep talking to people that put too much business logic in their components
and then complain about react's unmaintainability as the project begins to
have problems. Most of the time is because of poor component design and lack
of a clear state/data management

~~~
arvinsim
I am surprised that is still a thing given that React + Redux is very popular.
I would expect anyone delving in React to at least be aware of it.

------
ola
This article purposefully misrepresents React in favor of the author's own
framework Binding.scala, all the criticism are either superficial like class
being className (which is a good thing because JSX is not HTML) or has nothing
to do with React like JavaScript's dynamic typing system and handling of
asynchronous updates.

He also seems to believe that React is framework when it's a library, if his
knowledge of React is so shallow that he didn't even read the first sentence
on the React website I can't take his opinions on it seriously.

I don't like these kinds of articles which are only thinly veiled
advertisements that do not offer any thoughtful criticisms, what I would
really like is to hear from someone who has actually worked on a huge project
which includes React and what troubles if any they ran into.

~~~
RonanTheGrey
I agree, as I read the article I got the same impression. This sentence did it
in for me:

> However, after a few weeks, as I became more skilled in React

Do it for a year and a half and I'll accept your criticism. A few weeks is not
enough time to claim enough expertise to be making the claims the article
makes.

------
FLGMwt
Some of these grievances might be better titled "things that thew me off when
learning React".

I'm not quite sure how using "className" vs "class" materially affects a
complex project.

propTypes are pretty shallow in terms of checking, but I've seen them more as
something third party components should provide as metadata/documentation
rather than replacing a type system. Large project should rely on Flow or
TypeScript if they're worried about typings.

I'm not sure I follow the complaints against asychronicity? Maybe when dealing
with improperly complex components it becomes tricky and that I think takes
experience to get a feel for.

Additionally, if we're comparing what appears to me to be a synchronous two
way binding pattern to React, I think it's really just a matter of choosing
the wrong technology for a given preference. React and the omnidirectional
data flow pattern are directly opposed to that.

~~~
aphextron
>I'm not sure I follow the complaints against asychronicity? Maybe when
dealing with improperly complex components it becomes tricky and that I think
takes experience to get a feel for

I found this argument pretty confusing at first too. I think since the author
is familiar with Scala he may be used to the Actor style of async programming
used heavily in the Akka framework that abstracts most of the hard to
understand control flow away from the programmer
([http://doc.akka.io/docs/akka/2.4/scala/actors.html](http://doc.akka.io/docs/akka/2.4/scala/actors.html)).

It's a valid complaint, but as long as Javascript is the only choice for
developing on the web we don't really have an alternative.

------
mattashii
> 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.

How did the author come to this conclusion?

He only complained about issues he saw in React, he didn't really compare them
to how it would work in binding.scala. I'm sorry, but I find this post a badly
written example of `software A is bad and therefore you should use software B,
even though it is not examined critically`

*edit: formatting

~~~
throwaway2016a
The author of this article is the author of Binding.scala so presumably he is
an authoritative source on it. However, not an impartial one.

------
toast76
Article bashing React, written by the author of the library he suggests you
use instead.

------
abeaclark
[https://github.com/reactjs/redux](https://github.com/reactjs/redux)

------
htormey
I disagree with at least one of the authors critiques:

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

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."

Out of the box React is relatively spartan, which is great for small projects.
At scale it only really comes into its own when used in conjunction with other
things such as Redux and its wonderful ecosystem of middleware.

In this kind of situation, I would advise using something like Redux and
following the advice of Dan Abramov (Redux creator). He wrote a wonderful
article on how to split functionality between components and containers:

[https://medium.com/@dan_abramov/smart-and-dumb-
components-7c...](https://medium.com/@dan_abramov/smart-and-dumb-
components-7ca2f9a7c7d0#.6xmuhf2rx)

I think this is a great pattern to follow for larger scale projects.

"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?"

Facebook seems like a pretty complex website to me and they are all in on
React.

As to his points about the virtual DOM performance, I'd love to hear a more
experienced web dev chime in on that as my area of expertise is native
development.

~~~
RonanTheGrey
Redux (and various projects in its ecosystem) resolves alot of the criticisms
in the article. To this:

> As to his points about the virtual DOM performance, I'd love to hear a more
> experienced web dev chime in on that as my area of expertise is native
> development.

His example of an <li> with a <ul> is wrong. Setting that aside..

Depending on the operation and the browser, you can do anywhere between
2000-100000 more operations per second in a virtual DOM than in the browser
DOM.

The complaint that complex render functions are wasting precious resources is
valid, which is why documentation makes it very clear that these functions
should be as simple as possible and produce no side effects. Remember -
library, not a framework.

Additionally, it belies the question of - why are you writing a complex render
in the first place. In a well-structured app, components would be reasonably
small and render functions relatively simple, for varying definitions of
'relatively.' That is, you aren't doing complex number crunching in the
render. When I do React perf optimization, one of the most common errors I see
people make is have render functions full of complex logic and branching
render paths. If you are doing that, your component can be further broken
down.

Apparently Facebook is built on over 100,000 individual React components.
Damn.

~~~
htormey
I agree. Redux resolves a lot of his criticisms thats why I really didn't get
why the author dismissed it so quickly:

"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."

Given how widely used Redux is with React I would have expected him to expand
on this point some more and provide a meaningful critique. It's a shame that
the other parts of his series have not yet been translated into English.
Perhaps he elaborates on what he means by the above statement.

------
yawaramin
A quick correction to the following claim:

> ... 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.

Yes, that will happen ... but only if you don't assign a key property to each
of the `<li>`s. React uses the key prop to uniquely identify nodes that were
actually changed versus ones that were just moved around among their peers. So
if you're dynamically creating lists of nodes of the same tag type, you really
need to be giving them a unique `key`.

Also, it's not a framework, it's a library. A framework calls your code, a
library gets called by your code. With React you call `ReactDOM.render` or
similar.

------
sarreph
> 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.

Does anyone have any tips for avoiding this extremely irritating 'props-
nesting' (as I like to call it)? I'm pretty new to React, and the one thing
that's bugging me about it is that in more complex UI (for example, a toolbar
that independently controls a nested component), is how you can't just go
through a top-level component directly; you have to go all the way up and down
the chain. This gets very messy once you decide to change some of the
intermediate components fundamentally.

~~~
mfrye0
Yeah there is a bit of a learning curve there. I was doing the same when I
first started.

It really depends on what you're trying to do, but it really comes down to
storing state and data in a central location.

If it's a simple component, passing the on click callback to a child that
updates the parent master state is pretty straightforward. So for example
selecting an item in a list and updating the active item when a list item is
clicked.

If it's a really deeply nested component though, that can get a bit harder.
I've had some success passing simple string values via the context reference,
which makes the values accessible to all the children.

Another pattern I've used is having a state store similar to the flux pattern
using eventemitter. I'm using this pattern a lot on thebigpicture.io for the
editor page. There's two main columns in the page that are very deeply nested,
so I created a separate state store and individual components are able to
listen to changes from different events.

------
jondubois
I think React is a good framework but it's not as elegant as Google's
PolymerJS in my opinion. React's main strengths are its large community (which
means lots of plugins and add-ons) and its native device support (React
Native).

My main problem with React is that it's more complicated than it needs to be -
If following an architecture like Redux, you often end up with long complex
chains of reducers and components which makes the logic very hard to follow -
Especially if you like to split up your code across multiple files.

There are few things worse than having 10+ files open at the same time and
having to figure out which one(s) is/are the cause of your problem.

~~~
WalterSear
React isn't redux.

~~~
htormey
Sure, but its very widely used in conjunction with React especially in larger
projects. I think its fair game for critique in that context. Also, the author
of the article specifically called out Redux:

"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."

I like Redux but I think the actions/reducers structure can be a little
cumbersome to follow at first.

~~~
WalterSear
IMNSHO, Redux is a footgun, and adds so much boilerplate and code
discontinuity as to negate much of it's benefit outside of colossal codebases
and teams.

Instead of reasoning in one file, now you have to reason through half a dozen.
Poorly set up actions/reducers will _stay_ cumbersome to follow, and aren't
appropriate for every application.

However, none of it's problems are due to react.

~~~
htormey
I agree. Dan Abramov the creator of Redux has a whole article devoted to this
topic:

[https://medium.com/@dan_abramov/you-might-not-need-redux-
be4...](https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367)

A lot of the work I'm doing right now is in a reasonably complex react native
app with multiple screens. In that context its worth the added boiler plate. I
wouldn't use it for a one or two screen app with little shared state.

------
hoodoof
Nup - none of these criticisms seem valid to me.

And a particular comment about asynchronous programming - ALL JavaScript
requires async programming and you need to know how to properly handle it no
matter what you are programming.

------
umurkontaci
Well,

[https://github.com/facebook/react/wiki/sites-using-
react](https://github.com/facebook/react/wiki/sites-using-react)

------
iLemming
Every front-end engineer knows - React is a library and not a framework. From
my own experience one of the best ways to see where React shines is to try out
one of Clojurescript libraries, and there are plenty to choose from: Rum, Re-
frame/Re-agent, Quiescent, Om.Next. React plays extremely well with immutable
data-structures. Om.Next is mind-blowing awesome.

------
KayL
Having no experiences with it. The author calmed that is faster but the
benchmark result in below chart was shown different word:

[http://www.stefankrause.net/js-frameworks-
benchmark5/webdriv...](http://www.stefankrause.net/js-frameworks-
benchmark5/webdriver-ts/table.html)

~~~
yangbo
Given a component that contains n elements, and you want to update k elements
at a time, ReactJS requires O(n) time for virtual DOM differentiation, and
Binding.scala only takes O(k) time.

As a result, Binding.scala is fast when k < n (aka partial updating), even
faster than vanillajs written by a common human for some cases. Check the rows
"partial update", "select row", "swap rows", "remove row" in the benchmark.

~~~
localvoid
Nobody cares when it is 6ms instead of 3ms for partial updates. What is really
important is how fast you can create and remove huge amount of nodes
(switching pages in SPA, etc), because it is already takes a huge amount of
time, and Binding.scala just adds a huge overhead to this cases.

------
tomelders
Well, that's one way to turn people off to your new framework. Maybe something
got lost in the translation? Maybe this reads better in the original language?
Maybe not. But even then, as many people have already commented on, it's just
plain wrong about React.

------
cwyers
I don't know, Facebook seems like a pretty complex project and they use React.

------
jiyinyiyong
React is not good enough since it's based on JavaScript. Swapping the language
to ClojureScript or ReasonML, the situation will change.

