Hacker News new | ask | show | jobs
by undo76 3791 days ago
Am I the only one that thinks that the author is trolling? I mean, the final code has obvious flaws:

a) Difficult to read and mantain. (Compare with the version below).

b) Inefficient in a real world scenario as it has to recreate the DOM every time the model changes.

c) Difficult to test as it requires a DOM API.

d) XSS issues (Text returned from the service is not escaped in the DOM!)

e) Non isomorphic (Unless we have a DOM API in the server capable of emiting plain HTML).

Nevertheless, I agree that using React for such a trivial project would be too much, but there are other alternative frameworks that would fit for this kind of task (e.g. riot.js, Cycle.js, [Insert here your favourite one]).

My React version:

  const DATA = {    
    name: 'John Smith',
    imgURL: 'http://lorempixel.com/100/100/',
    hobbyList: ['coding', 'writing', 'skiing']
  }

  const App = ({ profileData }) => (
    <div>
      <Profile { ...profileData } />
      <Hobbies { ...profileData } />
    </div>
  );

  const Profile = ({ name, imgURL }) => (
    <div>              
      <h3>{name}</h3>
      <img src={imgURL} />
    </div>
  );    

  const Hobbies = ({ hobbyList }) => (
    <div>
      <h5>My hobbies:</h5>
      <ul>
        { hobbyList.map( (hobby, idx) => (
          <li key={ idx }>{ hobby }</li>
        ))}
      </ul>
    </div>
  );

  ReactDOM.render(<App profileData={DATA} />, document.getElementById('content'));
5 comments

Thanks for posting your React version and offering a bullet list of real points of critique.

That said, please don't use the word "trolling" to make what is essentially an ad-hominem attack against someone whose point you disagree with. The author probably spent at least an hour, if not multiple hours, thinking through a problem and presenting a solution as a blog post. Whatever you think of his argument, this is clearly not the work of the troll.

"He's trolling" has recently become the tech community's version of Salem's "She's a witch."

I agree that maybe "trolling" is not the most accurate description. The author seems to be a competent coder, so I am assuming that he knows that such a solution for view components is flawed at least and that it would be a nightmare to go that way.

My biggest concern with the original post is the next sentence, "If you want to use React, fine, I am not trying to convince anyone not to. I just want to show that components in a JavaScript application are quite simple to do and do not require any framework at all to do so." (The author has updated the post to clarify that "I am a proponent of using libraries and frameworks." I think that this was missing in the original post, I think that it would have been nice to add at the end of the post "Crazy, isn't it? Don't do it! Don't reinvent the wheel and tada-tada-tada...)

Not sure about the intentions of the author, but I think that the original post makes a great case to support the use of these frameworks and not the opposite.

Thinking through the deeply complex problem of how to display a static heading, image and three bullet points? This is master troll material. I LOLed greatly.
Without taking sides, understanding your application requires a fairly complete understanding of React, JSX, Javascript, the DOM, and how React ties all of this stuff together. Sure, your code by itself is quite small, but when you add React, it grows by the size of React.

On the other hand, just by knowing Javascript and the DOM, you can understand exactly what is happening in the OP's code.

Well, technically you don't need to know JSX, but it pays off to know it IMHO. Moreover, the DOM API is much more complicated than React API and the latest doesn't depend on the particular browser you are using.

But yes, to use a technology, you need to understand it.

Regarding the size, you are right, I wouldn't recommend to use React for such a tiny task.

IMHO, the JSX as used in this example is pretty obvious if you know ES6 syntax. The only "weird" part is curly braces for data interpolation, but even that is pretty semantically obvious.
Regarding size, a Mithril/MSX implementation would look about the same.
You make a fair point. That said, one of the nice things about React is that even a moderately experienced JS programmer can learn the basic mechanics (including how to use JSX) in a few hours. That’s a reasonable investment for a useful tool, and React has a much shorter learning curve than most of the larger JS frameworks.
I fully agree that his version has flaws, and I certainly am not convinced that he presents a credible case against using React. But to be fair, I think part of his rationale for doing things this way is to avoid the configuration needed to develop with React. I'm somewhat ignorant, so what is the necessary tooling/configuration needed to convert this file to something that can easily be executed in the browser?
It is a misconception that you need a lot of configuration to start with React. The minimum setup requires just to import the React libs in your webpage and to transpile your code to ES5 using Babel in case you are using JSX/ES6 (recomended).

Of course for bigger projects, it pays off to use an automatic build tool like webpack or gulp.

https://jsbin.com/keyuqohusa/edit?html,js,output

https://babeljs.io/repl/#?experimental=false&evaluate=true&l...

I think the issue people have with React is that a lot of tutorials assume you are already using NPM/Babel.

If you're using a module importer already then adding React to your stack is pretty easy. For example with JSPM:

$ jspm install --dev react react-dom $ npm install --save-dev babel-preset-react

Then add 'react' to your .babelrc preset.

In your ES6 javascript file you can now use react via:

import React from 'react';

----

That's it.

However, if you have none of that already set up... Then you'll naturally be persuaded that now is the time to get a 'modern' javascript environment setup and doing so can take time. It took me about 2 days of beating through RequireJS --> Webpack --> JSPM before I settled on the latter.

Figuring all that was difficult, but looking back on it was extremely useful to now have all my Javascript bundling done within JSPM rather than using some Django bundler, and downloading raw JS files from the internet without evening using Babel to help me write ES6/ES7.

This article was my first exposure to React, and it goes through the basics of building a very simple "list of people" using nothing more than a single HTML file. It doesn't even use JSX, instead showing you how to build the raw JS that the JSX would compile to. I found it to be a great introduction without a lot of overhead to learn.

http://jamesknelson.com/learn-raw-react-no-jsx-flux-es6-webp...

There are a few ways you could build a working site from undo76’s example. Unfortunately all the noise around modern JS does make it seem more complicated than it really is, but you can set up everything you need in about two minutes.

The only essentials you need are React itself and, because the example uses ES2015 and JSX code, Babel to transpile the script into more portable JS that will run in today’s browsers.

In practice you’d probably also be using Node/NPM to manage packages and a tool like Browserify or Webpack to resolve dependencies. I’ll use Browserify.

So, here is a complete working example. For the script, we’ll use undo76’s original code verbatim, and add imports of the React modules at the start of the file. Let’s call this index.src.js:

    import React from "react";
    import ReactDOM from "react-dom";

    const DATA = {    
        name: 'John Smith',
        imgURL: 'http://lorempixel.com/100/100/',
        hobbyList: ['coding', 'writing', 'skiing']
      }

      const App = ({ profileData }) => (
        <div>
          <Profile { ...profileData } />
          <Hobbies { ...profileData } />
        </div>
      );

      const Profile = ({ name, imgURL }) => (
        <div>              
          <h3>{name}</h3>
          <img src={imgURL} />
        </div>
      );    

      const Hobbies = ({ hobbyList }) => (
        <div>
          <h5>My hobbies:</h5>
          <ul>
            { hobbyList.map( (hobby, idx) => (
              <li key={ idx }>{ hobby }</li>
            ))}
          </ul>
        </div>
      );

      ReactDOM.render(<App profileData={DATA} />, document.getElementById('content'));
As usual, we need an HTML file to load that script, though it doesn’t need to do much else except provide a <div> with an ID where we’ll put the content that React renders. Otherwise just use your preferred boilerplate. Let’s call this index.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="utf-8">
    <title>React test</title>
    </head>
    <body>
    <div id="content"></div>
    <script src="index.js" charset="utf-8"></script>
    </body>
    </html>
Finally, we need the tools and React packages:

    npm init
    npm install --save react react-dom
    npm install --save-dev browserify babelify babel-preset-es2015 babel-preset-react
Now we can run Browserify to generate our output JS file (adjust the / to \ if you’re running on Windows):

    node_modules/.bin/browserify index.src.js -o index.js -t [ babelify --presets [ es2015 react ] ]
That will produce index.js, which is just the code from undo76 linked with React and then transpiled to a more portable level of JS that today’s browsers can cope with. (Incidentally, this is literally the first example on the Babelify documentation page, which gives you an idea of how routine it is once you’re familiar with these tools.)

Now load index.html in your browser of choice and enjoy. :-)

I suspect trolling too. It would be too easy to make his code more readable, like abstracting all those `addEventListener` and `document.createElement` and make some kind of factory for his Definitive Module Pattern.

Also, what's with that syntax color scheme?

Could you please point out where the XSS issues are?
Stupid me. I missread the code and did a proof of concept in jsbin just adding "</script><script>alert('XSS');</script><script>" as a hobby. Now I realise that I added it in the HTML view so I was just closing the original <script> tag. So, no XSS issues, AFAIK. I am updating my original response to reflect this.

Nevertheless, using a framework like React protects you automatically from accidentally adding XSS vulnerabilities.

Thanks, I thought I missed some XSS unknown to me in that code. Agree with you about React and other frameworks making it hard to accidentally introduce XSS.