
How to avoid rewriting your JavaScript application - mrnicehands
https://tech.polyconseil.fr/code-your-js-app-like-its-86.html
======
daliwali
The article opens with:

>Frameworks, libraries, package managers, guidelines… even languages and meta-
languages themselves are changing so fast that there's little to no chance a
common or standard way of building applications emerges.

...and then gives an example using React, JSX, and ES6 modules. This is just
my opinion but I think React + JSX will look about as antiquated and
irrelevant as jQuery in less time than it took jQuery to lose favor among web
developers, rendering the argument for longetivity moot.

At least jQuery solved the practical problem of non-standard JS/DOM
implementations, but now browser vendors have finally made basic things work
among each other, making it irrelevant in most modern browsers. React solves
what? Encapsulation? There's Web Components v1 right around the corner, and
dozens of competing frameworks that may take its place as the most hyped
framework.

~~~
jowiar
The fundamental problem solved by React is being able to express a UI as a
function from Application State to DOM, and not having to worry about manually
computing the changes to the DOM that need to occur to reflect the new state
of the world.

It changes the fundamental question of UI development from "How do I get from
where I am to where I want to be?", but "Where do I want to be?"

The funny thing about the particular example in the article is that React was
heavily inspired by event loops used in Game Development.

~~~
softawre
So.. data binding? Like backbone did, and knockout?

I know React has some things going for it, but data binding on the web is an
old trick.

~~~
jowiar
Not really "binding" per se -- mostly because "binding" implies you're
attaching events to objects and thinking about "changes", and object lifecycle
is still something you're concerned with.

React is more functional in nature -- A react component is, almost entirely, a
function that takes arguments and spits out DOM elements. React then diffs the
desired DOM with the current DOM, and computes the set of transformations
needed to update the UI to match the new state -- i.e. "Add a few rows to the
table, change the text in a particular span equal to 'boom'" or whatnot.

~~~
fullofit
That's just an implementation detail. All these declarative UI ideas are
variations of sprintf. Something, somewhere, is going to do a diff no matter
what, whether it's a virtual DOM or the browser itself.

~~~
munro
Try making a web app rerenders the DOM on any state change, it will be
extremely slow--the browser doesn't diff. :) That's why vDOM & diffing is
necessary. Also so UI inputs don't lose focus / selection state / etc.

~~~
daliwali
State change, eh? There's this, which diffs only local updates and doesn't use
a vDOM: [http://simulacra.js.org/](http://simulacra.js.org/)

Disclosure: I'm the author.

~~~
munro
Tracking changes to application state & translating to DOM changes is nothing
new, [1] it's what Angular, Angular2, Riot, Knockout all do, and doomed to
efficiently translating any complex state changes. [2] Not only that, feeding
application state in from an API will cause the all the dependent UI to
completely rerender.

[1]
[https://github.com/sapeien/simulacra/blob/master/lib/bind_ke...](https://github.com/sapeien/simulacra/blob/master/lib/bind_keys.js#L143-L148)
[2]
[https://news.ycombinator.com/item?id=12757722](https://news.ycombinator.com/item?id=12757722)

------
defundefun
Great article, but i think the op needs to take a look at redux. The best way
to use react is to have as little local state as possible. Once you accept
that the next question that comes to mind is where should i put all the logic.
This article does a good job enumerating the libraries that have been created
in an attempt to solve this question [1]. Also when you have all your state in
a single global map, you start wishing it would behave more like a database.

The problem with the redux react ecosystem is that it wants to be functional
and so it imports a lot of innovations done in functional languages, but in
the end js it's not functional and you end up fighting the language. For
example the reselect library [2] tries to implement selectors, but without
native inmmutable data structures its too painfull to use.

I see a lot of people trying to implement so much features that should have
been part of the language as libraries and i ask myself why not just use
another language that has all those features, i mean they are all compiling to
javascript anyways. Its madness.

[1] [https://medium.com/@jeffbski/where-do-i-put-my-business-
logi...](https://medium.com/@jeffbski/where-do-i-put-my-business-logic-in-a-
react-redux-application-9253ef91ce1#.sv0k0f9v4) [2]
[https://github.com/reactjs/reselect](https://github.com/reactjs/reselect)

------
ng12
Uh, this code is kind of crazy. Even in the "fixed" example. Why is he calling
instance methods on components? Why is he muddling with jQuery? And the global
click events? He started with bad principles and just implemented them better.

------
matchagaucho
While working on a ReactJS/Redux reducer, I had the same epiphany. "This is
basically the old Windows main() message pump!"

Redux really _is_ a beautifully elegant way to decouple global state and
actions from the UI.

~~~
acemarke
Yep - there was an article last year that pointed out the distinct correlation
between a classic Win32 WndProc and a React+Flux-style architecture:
[https://bitquabit.com/post/the-more-things-
change/](https://bitquabit.com/post/the-more-things-change/) .

But yeah, as I've said in a few recent comments, Dan and Andrew made some
excellent decisions while designing Redux, and those decisions have helped
Redux hit a sweet spot for concepts and use cases.

~~~
jrgnsd
Thanks for linking to the article. I remember reading something like that but
had no idea on how to find it.

------
orf
Interesting article, but I cant help but think every one of those points is
'fixed' in EmberJS (correct me if I'm wrong!). Central stores, central place
to fetch 'models' (data over Ajax), dependency injection so it's all mockable,
a run loop, simple and understandable data flows.

The central store and the run loop is very powerful. If you have two
completely unrelated components issue two fetches for the same model type but
different IDs (ie two different blog comments) Ember coalesces them into a
single request (I.e /api/comments?id[]=1&id[]=2) transparently. That's
awesome.

------
swang
isn't the jsx also wrong? you can't have 2 separate div's like that in react
right? you'd have to wrap them in another div.

render: function() { return ( <div className="title">{this.state.title}/> <div
className="button" onClick={this.handleClick}> ) }

~~~
mpc
yes, that will break.

------
underwater
The idea here is sound. It's essentially a reinvention of one way data flow in
Flux: data flows down to components, events flow back to a central point
(dispatcher in Flux, main.js in this example).

His implementation is a bit iffy though. How will his app look when there are
dozens of components? A single main.js module with dozens of data fetching
functions is going to be really hard to work with.

~~~
lisivka
It's typical MVC application, reinvention of TurboVision.

------
wry_discontent
I think this is the motivation behind Cycle.js

[https://cycle.js.org/](https://cycle.js.org/)

~~~
westoncb
I hadn't heard of cycle.js before, but looked into it a bit just now and it
seems pretty nice.

My only concern would be that I _hadn 't_ heard of it before, so I wonder if
it has significant traction and production readiness.

Anyone have thoughts on that?

------
hakanderyal
For managing side effects, redux-saga[0] is god-send if you are using redux.

[0]: [https://github.com/yelouafi/redux-
saga](https://github.com/yelouafi/redux-saga)

~~~
eiriklv
The idea behind redux-saga, to push all effects to the edge (handled by a
runtime), only handling descriptions of the actual effects doesn't have to be
limited to redux/redux-saga either. You can leverage generators + a runtime to
build all kinds of applications like this [0] (you can sort of do this without
generators too, but it's a bit more quirky when you cannot control/pause the
execution [1]). Easy testing (no more mocks/stubs in the traditional sense -
only data/descriptions) and predictability are just some of the benefits.

[0]:
[https://gist.github.com/eiriklv/a498112b3a73fc2b92975649924c...](https://gist.github.com/eiriklv/a498112b3a73fc2b92975649924cf5c3)

[1]:
[https://gist.github.com/eiriklv/b6cc681447a0939365e1ba044fac...](https://gist.github.com/eiriklv/b6cc681447a0939365e1ba044fac15d7)

------
lai
Isn't this why you should try to make your components as stateless as
possible?

------
carsongross
Another option, rather than going back to client-server style programming, is
that you could write your web app like it's 2004 and leverage the unique
network architecture it had (REST/HATEOAS):

[http://intercoolerjs.org/2016/05/19/back-to-the-
future.html](http://intercoolerjs.org/2016/05/19/back-to-the-future.html)

 _That is probably the biggest issue: no one cares about long-term support or
maintainability of UI applications nearly enough to actually create the
ecosystem that it deserves._

Absolutely. Not a lot of long term, slow thinking going on these days.

~~~
ggregoire
Please, can you stop promoting your lib in every topic about JavaScript...

~~~
carsongross
I try not to unless it is reasonably relevant. In this case, the author is
suggesting a way to deal with the fact that we are building apps like we were
back in the 90's, but in javascript, and I have an alternative suggestion,
which is that we build them like we did in the 00's.

But I appreciate that people who have seen it before are sick of seeing it
again.

------
vampolo
Nice article but i think it touches two problems, but then offers a solution
to one.

Every program has a code structure. Certain programs have better code
structure than others. These are properties independent from the programming
language. Javascript evolved from a single entry point, being the [in]famous
$.ready() to set behaviors of some html elements, to full blows ES6 single
page applications.

It all started as a toy language.

But it simplicity is also its flaw: it enables every human with a not so deep
understanding of computer architecture to write a button that changes color on
click. The absence of a type system and a solid class paradigm (introduced in
ES6) spoiled programmers to pass any object down to any function breaking well
known software paradigms: Law of Demeter
([https://en.wikipedia.org/wiki/Law_of_Demeter](https://en.wikipedia.org/wiki/Law_of_Demeter)),
Open/Close Principle
([https://en.wikipedia.org/wiki/Open/closed_principle](https://en.wikipedia.org/wiki/Open/closed_principle))
and the Liskov Substitution Principle
([https://en.wikipedia.org/wiki/Liskov_substitution_principle](https://en.wikipedia.org/wiki/Liskov_substitution_principle)).

I'm in the Web space professionally from 15+ years and those are the 3 rules i
see JS devs break the most, generating complected code (for more understanding
of the term have a look at [https://www.infoq.com/presentations/Simple-Made-
Easy](https://www.infoq.com/presentations/Simple-Made-Easy) ), hard to
maintain and extend like the example shown in this article.

The advice to build interfaces around data structures, proposed as solution,
is no different than the Liskov Substitution Principle.

The other problem the article cites is the event loop.

At the time o $.ready() there was no event loop. Developers were just
attaching functions to user events: clicks, hovers, blurs, focus. Just a
direct mapping between an element and a function. You can simply come to the
conclusion that the trigger and the action to be performed were not loosely
coupled, but indeed tight together. Easy, yet not scalable.

Tieing events to the dom structure was another sin opening more questions:
should an element that is not interactable fire events? bubble them ? every
browser had its own answer to those questions. Things got even more
complicated with single page applications which html element in the page can
be added and removed. So here comes the event loop, like other well known ui
stacks did in the past.

The concept of an event loop is not a novelty, it is indeed bound to the
architecture of our computer: clock cycle, interrupts, kernel events. In the
case of windows is the well known WPF
([https://en.wikipedia.org/wiki/Windows_Presentation_Foundatio...](https://en.wikipedia.org/wiki/Windows_Presentation_Foundation))
which has, among a lot of other things like any Microsoft product, the concept
of a dispatcher that is central to the flux architecture.

In 2015/2016 with React/Flux Javascript and the Web is moving out of puberty,
enabling developers to write clean, decoupled, extensible code. Thus no all
devs are ready to grasp those architecture that are so obvious in other
ecosystems. To cite Poul-Henning Kamp in A generation lost in the bazaar
([http://queue.acm.org/detail.cfm?id=2349257](http://queue.acm.org/detail.cfm?id=2349257)):

"So far they have all failed spectacularly, because the generation of lost
dot-com wunderkinder in the bazaar has never seen a cathedral and therefore
cannot even imagine why you would want one in the first place, much less what
it should look like. It is a sad irony, indeed, that those who most need to
read it may find The Design of Design entirely incomprehensible."

my 2 cents

------
defundefun
Or code like its 2016 and use something like what its proposed by elm,
clojurescript's reagent or posh libraries.

~~~
GoToRO
Unfortunately a year is never an argument.

~~~
defundefun
They change the original title i was just making a reference to that.

~~~
GoToRO
I see.

