Hacker News new | comments | show | ask | jobs | submit login
Boiling React Down to Few Lines in JQuery (hackflow.com)
156 points by Suor on Mar 8, 2015 | hide | past | web | favorite | 32 comments



I use something a little similar where I work. No one would be on board with something like React but I've documented a way to write our code that does something similar to this post. We use js "classes" (Both Function.prototype and now js classes with babel) and lo-dash templates to make it a little nicer.

Example:

    function MyComponent(element) {
        var instance = this;
        instance.element = element;
        instance.history = [];
        instance.state = { myKey: 'someData' };
        instance.template = _.template($('my-template').html());
        instance.setupHandlers();
    } 

    MyComponent.prototype.render = function() {
        var instance = this;
        instance.element.html(instance.template(instance.state));
        instance.history.push(deepcopy(instance.state));
    }

    MyComponent.prototype.undo = function() {
        var instance = this;
        instance.state = instance.history.pop();
        instance.render();
    }

    MyComponent.prototype.setupHandlers = function() {
        instance.element.on('change', '.my-input', function(e) {
            instance.state.myInput = $(this).val();
            instance.render();
        });
    }

    
This is of course a very simplified version but it should give you an idea of what I'm talking about.


I like how you redundantly alias `this` to `instance` except in the only method that needs it ;)


Haha yeah that was stupid. With the fat arrow "=>" I'm hoping to be able to get rid of it in most instances. I know I could mix this/instance but I'd rather use "instance" everywhere for consistency even if "this" works. I'd love to hear other's thoughts on the matter!


You're example is the perfect example of what not to do and why React, Angular and such exist: STATES. You want your view to be data driven.It means that your component should be STATELESS.

There are other issues such as event delegation,cleaning up event listeners,... that will make your solution hard to scale past simple widgets.And before you know it,you'll be writing your own complicated framework that does less than Angular or React.


> that will make your solution hard to scale past simple widgets.

I am fully aware of this issue, again, this is a stop-gap between the jQuery mess we had and proper framework. This is not being used to run the whole front-end, it's only being used for components that are loaded on a page. And in fact the one page that we have that does a full re-draw on every change is actually extremely fast, you don't even notice it. Again, this is not to say it's the end goal, just a step on the staircase to a JS framework. Just getting away from building a component in PHP then modifying it in JS has been a huge win. My rule of thumb is logic should only be implemented in 1 language and so if you need to update/modify anything on the client side (which we almost always need to do, this is a Web App and not a website with some JS sprinkled in, even if that's how it started) you need to do it all in JS or else you get into a case all too easily where you edit the JS or PHP and not the other. Not to mention that if we wanted in the future we can alway render the first load on the server (using JS) and then subsequent renders could happen on the client with the same code.


A web app always has a state machine somewhere, even in functional languages. The question is whether the app's state is internal (mutable state) or external (write a state transition function and let the environment pass the state back to you on the next iteration).

I think the jury is still out on whether storing all application state in a single state object (as in Elm) scales well beyond toy examples. All the state is exposed which doesn't seem so good from a data-hiding point of view.


> I think the jury is still out on whether storing all application state in a single state object (as in Elm) scales well beyond toy examples.

I'm not familiar with Elm, but what do you mean by this? Even if all the application state isn't literally in a JS object like {users: [...], messages: [...], ...}, it's going to be in multiple variables like UserStore and MessageStore. There's really not a big difference other than the syntax of accessing them. But perhaps you're hinting at a drastically different approach to application state.


Elm [1] is not JavaScript. It's a pure functional language that compiles to JavaScript. There are no mutable variables in Elm as you'd normally think of them, but there are streams (called signals) and state machines.

The issue is that you can't really write UI components as you'd normally think of them; everything needs to be divided up into a separate models and view functions. The state of every single widget in the page (recursively) needs to be represented somewhere in the application model.

[1] http://elm-lang.org/


It seems to work reasonably well for the two non-toy apps I've worked on that use a single state object. There are two key rules required to make this work, however:

1. For each domain, state can be modified in one place (in React, a store).

2. For each domain, state can be read in once place (a Presenter).

This preserves data-hiding for the most part, and keeps you from having to play hunt-the-wumpus when you need to change the data structure.


Om also stores all app state in a single object, but lets you give components a window into that state ('cursors') in order to maintain modularity. If there turns out to be a problem with this general approach, it won't be a data-hiding one.


It's sad that your colleagues' lack of open-mindedness about adopting a framework is forcing you to create a less-well-specified, less-documented, implicit framework.


I think its more surprising that his/her collegues are down with ES6 through babel but are yet scared of something like React..


We are using babel because I already got gulp into our code base and so adding babel was pretty easy to get in (also the benefits were easy to explain). While I could slide react/angular in our bower config easily I would need to document how to transition from what we have to the new JS framework. More than anything I worry about moving too fast. Getting switched from jQuery mish-mash of code (global functions and variables everywhere and everything in a doc-ready) to what I have above was a big hurdle that we still aren't over. I'm trying to ease everyone in without leaving anyone behind. I know what we are doing isn't the best approach but it's better than what we had before and will be many times easier to move to a JS framework.


As I said in the reply to the child comment it's more of a "we can't move that quick without people falling off". I'd love to adopt a JS MVC or even just something like React but it would be too much of a change. I'm trying to ease everyone in with a combination of ideas that I've pulled from various frameworks. I don't for a minute think what we are doing is the most efficient (redrawing the entire view for every little change? Terrible) or even best practice but we have to start somewhere and trust me, anything is better than what was there before. I'd love to hear ideas on a better way to accomplish this and ease the transition.


React is more than a few lines of clever Javascript.

It's also a philosophy of UI composition. It's also a philosophy of data consumption. It's also a philosophy of code structure.

Having written my share of code with both, I now prefer composing UI's in React. It's easier to get simpler code maintenance and better performance with React.


i thought it was a good simplistic illustration of react's concepts using a tool everyone already knows


React also has two years of battle-testing at Facebook and Instagram. I'm not a fan of Facebook the product, but they've got some great engineers and I trust their code.


There are sure some things I haven't covered. The major one is components, which make a big deal in factor, reuse and composition. But the post started to be too long and loosing point so I skipped it.

There are also ideas beyond React I left aside. I will probably write some follow up post later.


> I want to stress this once more – for an average app you can skip React or other virtual DOM at start and only go for it once it gets too slow (or never).

I don't think this is good advice. It would be better to just start by using something like React, then if things get too slow, implement shouldComponentUpdate, because you will almost certainly need something that can make efficient DOM updates instead of just naively recreating whole DOM trees.


Using framework has its cost, so you can be better of if you understand clearly what you are doing. OTOH, framework brings structure so it's less probable you skrew up your design.


I think your piece does a great job of highlighting the design principles behind React and friends, but in reality, I see nothing wrong with having your cake and eating it too: understand the principles but still use a battle-tested framework with a strong community around it. I don't see why everyone should reinvent the same abstractions. Your last sentence really nails it.

Great piece though. It's good for programmers to understand how powerful the concept can be of factoring state out of actions of your app.


shouldComponentUpdate is nontrivial to implement when you're using mutable application state. I feel like all React tutorials should at least mention this, but sadly most seem to say something like "do not worry about performance until it becomes a problem, then just implement shouldComponentUpdate."


If you have a slow react component that uses mutable data structures for state, and implementing shouldComponentUpdate is hairy, you could always switch to using immutable data structures for that component's state instead. That change alone is very easy. From there, implementing shouldComponentUpdate is very straightforward.


If you were to put the event bindings in the markup instead, some of the examples would look very similar to Riot 2.0 [1] tag definitions, although it uses a more Glimmer-like approach which only looks at the bits which can change based on the template, instead of a Virtual DOM.

[1] https://muut.com/riotjs/


I've never had to use a front end framework.

I still use jQuery.


What's the biggest "program" you've written using solely jQuery? I recently completed something in the range of 3k lines using only jQuery and prototypical inheritance and realized later it probably could have very easily benefitted from picking up Backbone, at the very least to hold state better than sticking it in an object on the base class in various ways.


Even backbone isn't worth the added complexity IMO.

All these frameworks make you write more code than needed... and because people started to feel it wasn't worth it, their latest pitch focuses on speed. They say the "virtual DOM" is the future, and if you're not diffing your state to re-render the DOM you're not a serious developer.

I still don't see the benefit. I've written 15k lines of javascript code in some apps. My components have state and I re-render as needed, and as long as you separate code between components it's fine.

How many times have you been using a js app and thought "wow this DOM is slow?" You don't. It's either 0.1 sec or 0.2 sec to re-render the whole component/widget. 99.9% of the time a website is slow because the server requests take too long. Every once in a while you'll see some crazy CSS3 animations that make things unresponsive.

The people who go on about having a virtual DOM run benchmarks on thousands of elements... I don't know about you, but I'm never rendering thousands of elements at a time. Ajax/pagination works fine for extra data. I did write a very simple template system and event management system... but I'd rather do that than add the complexity of a framework. Dealing with a framework to make things work in "the X way" is wasting everyone's time. And then the next Angular or whatever comes along... and everyone wastes more time learning the latest version. This has turned into a rant... but I just want to say I'm happy as a coder who avoids frameworks at all costs. At the same time I try to use as many libraries as possible. Libraries save time, frameworks waste time.


Everything you say about DOM performance is decidedly not true on mobile.


I often feel like Javascript frameworks is dominated by 'experts' claiming how the proper way to write Javascript apps is now to share their opinions.

I've yet to run into any problem that were supposed to happen using jQuery and vanilla Javascript.

Even outside of Javascript, I stay away from using full blown frameworks. Even libraries that you think will be perfect for your use case turns out to be a drainage of resource learning, and now being bent to the will of the author's opinions. For example, Celery is a complete piece of shit. The amount of bug, and workarounds that one must experience vs. writing something on your own using RabbitMQ or even just redis, it's clear to me. Same with giant PHP frameworks or RoR vs. Flask. Even microframeworks that focus on not being a framework comes with the some opportunity cost, however being better than the monolithic frameworks that whines and decides to leave you in the dark because you did not share the same opinions.


about 5k. Funny I thought about the same thing but in the end I considered the amount of work that would be required vs.something that is already working well, easy to understand, skillset being very low if someone needs to pick it up (just jQuery, not even weird object orientated bull crap).

Yup, just one single .js file written in jQuery. I am however, curious about React.js, and want to experiment with new components, I doubt I would use Backbone.js however.

It took far longer, and more bugs using Backbone.js than using jQuery. I don't know why people are so obsessed with Backbone.js, modularizing, object orientation with Javascript, the language was not optimized for such purposes, it's only with the server side javascript boom with node.js that we are seeing this heavy shift towards Javascript, but I treat Javascript like the second class citizen it really is, and I think it's rather naive to suddenly start using it for everything just because you can and everyone is doing it.


There are a lot of factors that make a framework either worth it or not. Here are some that lean towards framework.

* Is it an application (google docs?), if not, you may not need a framework.

* How large is the team? For a solo project, a framework offers less of a consistency benefit. In a group, having people implement the same way can be important, and a framework helps a lot.

* Are you managing a lot of application state in javascript?

I'm out of time, but those are some of the big ones. I've used frameworks in the past, but we're currently doing a classic wizard-style application, and the frameworks don't offer us a lot. If it was less site & more application, I would be pushing for one of the popular frameworks to help manage complexity. Frameworks bring additional complexity, and they need to mitigate a certain amount of complexity to be worth it.


im also building a wizard style app. I do feel like react could help but the work it takes to reimplement it seems unprofitable.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: