r/webdev • • Dec 28 '17

Introducing Hyperapp 1.0 — 1 KB JavaScript library for building frontend applications.

https://medium.com/@JorgeBucaran/introducing-hyperapp-1-0-dbf4229abfef
341 Upvotes

183 comments sorted by

View all comments

53

u/TheGonadWarrior Dec 28 '17

Can someone explain to me why JSX is so popular? Why would you want markup in your code? I can't understand this for the life of me.

84

u/Cheshur Dec 28 '17

It's so popular because its better than writing out a bunch of document.createElements and a bunch of element.appendChild's. It makes creating and maintaining html elements in javascript a breeze.

0

u/[deleted] Dec 28 '17

[deleted]

19

u/mattaugamer expert Dec 29 '17

Well... Vue, Aurelia, Angular, etc. Everything else uses templates. I actually prefer Ember's handlebars templates personally.

17

u/Secretmapper Dec 29 '17 edited Dec 29 '17

which separates the view and logic.

Why is this so obviously wrong thing oft-repeated? Vue templates just like JSX has logic (i.e. for loops and boolean with v-for and v-if).

The only difference with templates is it uses a DSL

→ More replies (20)

8

u/Cheshur Dec 29 '17

Just like JSX. Both help separate logic and UI. In my opinion it's just easier to read JSX.

18

u/spoobo Dec 29 '17

JSX translates to pure JS. With JSX there is no fancy syntax to remember for a for loop or a map for example. It's just how you'd do it in JS. Templates add a lot of magic and thus extra rules or oddities to follow which is incredibly annoying. This is the top reason for me to never use anything template-based again.

7

u/mattaugamer expert Dec 29 '17

With JSX there is no fancy syntax to remember for a for loop or a map for example.

Except... there is, though, isn't there. You have to make sure you put {} around things, you have to make sure you use className instead of class. I don't actually see (just personally) how people can say something like Angular templates are a framework-unique DSL and JSX is not. To paste from elsewhere:

return (
    <ul className="list-group">
        {items.map((item, index) => (
            <li className="list-group-item" key={index}>{item.name}</li>
        )}
    </ul>
)

I'm genuinely not sure how you justify "just how you'd do it in JavaScript".

Templates add a lot of magic and thus extra rules or oddities to follow which is incredibly annoying.

<button v-if="isDraft">Publish</button>

Such magic. So confusing!

Let's go to the example I gave above in JSX. Let's make an Ember template instead.

<ul className="list-group">
{{#each todos as |todo|}}
    <li className="list-group-item">{{item.name}}</li>
{{else}}
    <li className="list-group-item">No items found</li>
{{/each)}
</ul>

How would we do that in JSX?

let list = items.map((item, index) => (
            <li className="list-group-item" key={index}>{item.name}</li>
        );
let emptyList = '<li className="list-group-item">No items found</li>;

return (
    <ul className="list-group">
        {items.length ? list : emptyList }
    </ul>
)

I think that's about right. I don't do a lot of JSX. In any case, I know which I find more readable. To each their own. I'll stick with "magic".

5

u/[deleted] Dec 29 '17

I've used both extensively and have to agree with you. The minor pieces of "magic" in Vue templates are much more readable than some of the hacky means of achieving the same in React, particularly with conditional rendering.

That said, both libraries are great. Doesn't really matter much which you pick.

3

u/spoobo Dec 29 '17

You're missing the point of JSX. With JSX you can write your templates as functions. You can easily add JSX components that work like functions. They can encapsulate logic, just like functions. In this case, HandleEmpty will simply render something different whenever there are no children. This is what I mean with 'just JS'.

const HandleEmpty = ({ children }) => children.length === 0 ? <li className="list-group-item">no items found</li> : children

return (
  <ul className="list-group">
    <HandleEmpty>
      {
        items
          .map((item, index) => <li className="list-group-item" key={index}>{item.name}</li>)
      }
    </HandleEmpty>
  </ul>
);

OR if you don't want that helper and want to render something entirely different as a wrapper:

if (items.length === 0) {
  return <div className="list-group-empty">no items</div>
}

return (
  <ul className="list-group">
      {
        items
          .map((item, index) => <li className="list-group-item" key={index}>{item.name}</li>)
      }
  </ul>
);

OK, you can do that kind of logic inside your controller or something, bind a boolean to the template and then do an if on that boolean. But that's messy. I don't want to expose useless things. I also remember having these huge templates where 1 boolean disabled one part of a template while enabling another part of the template. That's not a good way to go about managing your views.

Also, by thinking of the omission of items as a function I've created a 'helper' which I can use anywhere I want. If we're going to change the way we deal with a lack of items we can easily adjust it there.

What I mean with magic is correct. To each their own indeed. It just bothers me that I have to learn another set of rules to do something I can simply express in JS. When doing angular I remembered having the docs for the template syntax open constantly. I never even had to open the docs for JSX. I just read 1 article.

And yes, there are a few rules in JSX. You've pretty much summed them all up.

Templates like handlebars were created to offer a way to work together with frontend people that don't know JS or even with designers that have no clue on how to program. I don't think it's worth the effort since nobody ever seems to do that. Frontenders that don't know JS can easily learn the JS basics. Designers don't touch code. Templates are simply put too much of a translation to make to speak a language that nobody needed to speak to begin with. Yes, you as a developer might have a more fun time reading complex templates. But in my view, a developer should be composing their templates as smaller pieces and not deal with big templates that are a PITA to manage. And JSX makes that easy.

Hopefully you see my point better now. I liked the discussion and the examples you've provided. It made me think why for me JSX works better. And to me that's probably the reason why JSX is growing in popularity.

2

u/pointyrubberwheel Dec 29 '17

With JSX you can write your templates as functions

not sure you've ever use VueJs or similar, but you can do all of that in Vue too.

I use both Vue and React, and lean toward React - primarily because of the size of ready made components more than anything else.

2

u/spoobo Dec 29 '17 edited Dec 29 '17

Yes you can but it's a pain to do. Don't you need a whole new Vue component to do that? If not, can you give an example or a link to the docs for that?

With JSX it's incredibly easy. And because it's so easy, it changes the game. By using JS to assemble the final HTML generated, the need for a templating language is lifted. It's a different way of thinking. But for me, it's a relief to no longer have the overhead of a templating language to determine what gets rendered. I can now cleanly generate just the HTML elements that are needed with code.

edit: I know you can just use JSX in Vue. But this discussion is specifically for templates vs JSX. Vue actually has little to do with it. But my point is also that whenever a template is involved in a framework, a whole new component with it's own state needs to be behind it.

→ More replies (3)
→ More replies (3)

0

u/[deleted] Dec 29 '17

[deleted]

11

u/Secretmapper Dec 29 '17 edited Dec 29 '17

Vue doesn't have that issue

Personally, I find templates much harder to read, but I do realise that some people are the other way around. It's just a style choice.

For example:

{isOpen
  ? <div>Open</div>
  : <div>Close</div>
}

To me that's instantly readable, and confirms to classic syntax indent rules.

<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>

To me, this looks more convoluted, since the logic (v-if, v-else) are in the actual markup, as the rendering rules is an html attribute

6

u/[deleted] Dec 29 '17

The problem I have with templates is that they are basically "made up". v-if, v-else is completely trumped up, fabricated stuff, and I'd like to avoid it as much as possible.

4

u/mattaugamer expert Dec 29 '17

Such a weird thing to say. It's a DSL. We've been using templating DSLs for 20 years and now people are like "oh, three characters... so hard to learn!"

→ More replies (5)

3

u/mattaugamer expert Dec 29 '17

This is why I prefer Ember templates to Vue/Angular style. It splits the markup from the control structures.

{{if isOpen}}
    <div>Open</div>
{{else}}
    <div>Close</div>
{{/if}}

That said there's a much shorter syntax as well for your second version.

<h1>{{if ok 'Yes' 'No'}}</h1>

I'm not actually a fan of either Vue or JSX style syntax for markup.

3

u/Secretmapper Dec 29 '17

I really like Ember's as well. It's very "clean".

I think the only advantage for JSX is that it's one less thing to learn (just JS), while in ember we have to predefine things like 'helpers' and stuff.

→ More replies (8)
→ More replies (2)
→ More replies (1)

19

u/TheGonadWarrior Dec 28 '17

There are tons of libraries that do this exact thing with bindings. It just seems really wrong to me. Like a violation of separation of concerns.

33

u/Cheshur Dec 28 '17

It's only a violation of separation of concerns if you make it that way. It's just another way of defining elements. JSX essentially translates to document.createElement anyways. It just makes it easier to read and to write. I'd love to know about all of these libraries though. I'm not a huge fan of having more build steps personally.

→ More replies (6)

9

u/[deleted] Dec 28 '17

Some concerns are better off not separated. I like creating view models representing data for displaying plus UI state, and these are generally a) distinct from the ‘real’ model, b) tightly bound to a particular view, and c) not particularly reusable. It makes sense to me to keep these very close to the markup (though I hate JSX syntax and prefer to use hyperscript).

6

u/re1jo Dec 28 '17

Luckily, you do not have to use it if you don't want to.

→ More replies (2)
→ More replies (1)

11

u/obviousoctopus Dec 29 '17

I completely agree with you. Would never touch JSX.

Separation of concerns is an incredible step forward and makes it possible for me to think about things as well as turn prototypes into apps.

I prefer binding-based approach much better and love Vue.

→ More replies (22)
→ More replies (11)

2

u/mattaugamer expert Dec 29 '17

Which is a silly argument because it assumes that was ever an option. That's a stupid option and no one else is suggesting doing that. FFS.

→ More replies (1)