7 ms·
The arguments against JSX and React requiring many small components are very surface level and sound like "we couldn't figure out how to make it work for us so
by guntars 10y ago
The arguments against JSX and React requiring many small components are very surface level and sound like "we couldn't figure out how to make it work for us so it must be impossible".
1. This was mentioned already, but, yes, you can use ternaries and boolean logic for simple conditionals (loggedIn && <a>Logout</a> || <a>Login</a>)
2. When you need more markup, put them in an if-else statement in the same render function.
render()
if (loggedIn) {
var login = <a>Logout</a>
else
var login = <form onSubmit={ ... } />
return <div>
{ login }
</div>
3. With SFC it's trivial to split these out into new components. You can even use bound methods to reuse the component state and props.
class Navbar {
LoginForm = () => {
if (this.state.loggedIn) { ... } else { ... }
}
render() {
const {LoginForm} = this
return <div>
<LoginForm />
</div>
}
}
4. And finally, what stops you from creating a custom component that works like this?
render() {
return <If cond={ this.state.loggedIn }>
<Then>Hello { this.state.userName }</Then>
<Else>Please log in</Else>
</If>
}
There's a continuum of ways you can structure your code, it just takes some experimentation to find what works for you.
After working with Angular templates for a long time and then switching to JSX, I'm never going back to having my markup in a string blob with magical attributes that make it do stuff.
- vasachi 10y ago4. This won't work if one of the branches errors, because they are both evaluated. You can, however, pass a callback. But a simple ternary operator does look better.
- jmcdiesel 10y agoAfter making some simple <If> <Loop object="">, etc custom components.... I've wondered why they don't exist in react by default, or arent the common pattern. They are very readable... maybe people just dont like the "logic" in a tag... i guess... whatever, made for some really readable code...
- jetter 10y agoRegarding <If> component - here is the guy that suggested this and then admitted that this is a bad approach in a long run: http://stackoverflow.com/a/26152067/1132016 http://stackoverflow.com/a/26152067/1132016
- straye 10y agoUsing <If> combines the worst aspects of custom SGML template markup languages and the complexity of React but with additional runtime overhead.
- natmaster 10y agoTurns out javascript is a quite reasonable language and already does that great.
- madeofpalk 10y agoI would rather 'regular' JS functions like .map() rather than React-specific functions like <If> and <Loop> (not to mention the namespace clash with existing JS keywords)
- ggregoire 10y agoThank you for fixing the misleading information from this article. I would add: 1."now you have to create 10 functions to get input from 10 inputs". Or you can learn JavaScript: handleChange(event) { this.setState({ [event.target.name]: event.target.value }) } 2. "Redux sounds like a synonym of verbosity, as well." Nobody forces you to use Redux. https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367#.bw11ampib https://medium.com/@dan_abramov/you-might-not-need-redux-be4...
- akhilcacharya 10y ago> [event.target.name]: event.target.value Dumb question but I've never seen this syntax before. What does it do or what is it called? (The brackets)
- prodigal_erik 10y agoComputed property names. Any expression whose value can convert to a string or symbol will work. ES6 added them: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- akhilcacharya 10y agoExcellent, thanks!
- nobleach 10y agoIt's not a dumb question at all. It's relatively new, and I would implore the originator of that comment to take a different tone. It requires a newer browser or some sort of transpilation step. (You're probably already using one if you're using React) Most of the React community has forged forward with ES6/ES2015, so learning that is definitely a part of the process.
- mudetroit 10y ago
- jetter 10y agoI think your comment just proves the point of the original post. Your examples are still not good enough for me in terms of syntax and real work with html guys (specifically, <If><Else> has some quirks). I've gone through these things, and the pain&negativity about Angular 1 which translates to negativity to all template engines was also mentioned in the post.
- halis 10y agoJSX is awesome. It's just JavaScript, you can do whatever you want... return ( <Foo> { selected ? <Bar /> : null } </Foo> ); or let children = []; if (selected) children.push(<Bar />); if (blah) children.push(<Blah />); return ( <Foo> { children } </Foo> ); or const bar = selected ? <Bar /> : null; return ( <Foo> { bar } </Foo> );
- petre 10y agoOur Perl5 CGI.pm codebase used to look like that (html + logic). Fortunately we switched it over to Mojolicious and it became manageable. Not going back there thank you.
- SonicSoul 10y agoAfter working with Angular templates for a long time and then switching to JSX, I'm never going back to having my markup in a string blob with magical attributes that make it do stuff. why would you do this in Angular? i thought the whole point was to use html templates in separate .html files. as for "magical" attributes, angular2 moved away from that and is using mostly native html attributes. i.e. [disabled]="x" [hidden]="x" (click)="myfunc()". Can't imagine it being more intuitive than this.
- lpa22 10y agoJSX actually makes it more intuitive than that by having 0 reason for even needing to know when to use square brackets vs parenthses. It's simply curly braces and vanilla JS
- SonicSoul 10y agothis is a different statement than the sentence i responded to. square or round just indicates the direction of the binding. everything in angular is also vanilla js.
- dismantlethesun 10y agoI think what he means is that control statements don't exist in JSX. You have to write Javascript to do if-statements, looping, etc. In React, there is no 'direction' of binding---its all one way, just like in vanilla Javascript, and in fact no binding on anything except low level elements' like divs. Components only receive props, which do not do anything at all until you write code that reads them and runs operations based on their values. Thus components are simply function calls (it's what they compile to anyways), and JSX is just a syntax to write functional code.
- SonicSoul 10y agoi don't see how sprinkling if-statements in your html is cleaner than "magical attributes" but thats just me :)
- dismantlethesun 10y ago> And finally, what stops you from creating a custom component that works like this? I wondered what the issue was myself, so I actually implemented that pattern in a codepen, then looked at the compiled form of the JSX to Javascript. The essential issue is that the value of a prop is always evaluated at runtime, regardless of if the prop is actually used. In the case of props.children this means that <Then> and <Else> are both evaluated, and thus rendered, and only one of them is actually used. Thus you can't have conditionally rendering children, unless you've written them to be okay with failing at a render, with a blanket state---which is what most people are trying to avoid writing into their components, and simply want to conditionally render in a higher level component.
- Keithamus 10y agoWrapping them in methods is an easy way to fix that... but not sure if it is any cleaner. render() { return <If cond={ this.state.loggedIn } then={() => `Hello ${ this.state.userName }`} else={() => `Please log in` } /> }
- spion 10y agoOr with an algebraic Maybe data type {this.state.user.case({ some: user => `Hello ${ user.name }` none: () => `Please log in` })} Or for async requests that are in progress, an algebraic 3-state type: https://twitter.com/Tholle1234/status/804796967222202372 https://twitter.com/Tholle1234/status/804796967222202372
- Untit1ed 10y agoYou can get around it with a Babel transform: https://www.npmjs.com/package/jsx-control-statements https://www.npmjs.com/package/jsx-control-statements Disclosure: self-promotion. It's really frustrating that I see this React-is-crap-because-no-conditionals come up again and again but if you want them all it takes is an npm install and a line of babel config :(.
- flopsey 10y ago
- floriferous 10y agoNot sure I understand your 3rd pattern, what does const {LoginForm} = this; do?
- hokkos 10y agoIt destructures this, to get the LoginForm property, it could be written <this.LoginForm> because even if it starts with a lower case character that are transformed as string when there is a dot it is transformed as object : <component /> compiles to React.createElement('component') (html tag) <Component /> compiles to React.createElement(Component) <obj.component /> compiles to React.createElement(obj.component)
- deleted 10y ago[deleted]
- tmnvix 10y agoIt is basically equivalent to `LoginForm = this.LoginForm`. It is called destructuring and is one of the nice conveniences of es6 javascript. Importantly you can also do this: var o = {p: 42, q: true}; var {p, q} = o; console.log(p); // 42 console.log(q); // true
- orange888 10y agoWhen I see examples like this, it reminds me just how elegant & simple Mustache.js template can be: Mustache.render( "{{#loggedIn}}Hello{{userName}}{/loggedIn}} {{^loggedIn}}Please log in{{/loggedIn}}", state );
- yeskia 10y agoElegant & simple?
- orange8888 10y agoElegant & simple!
- bschwindHN 10y agoWhat exactly is elegant and simple about that? I feel like this kind of syntax would break down on more complex examples, is that not the case? What would it look like with multiple conditions (say something like A && B || C)?
- orange8888 10y agoWhat on earth does not break given more complex examples? That's a bit of a non-argument. The mustache example is a direct translation of the jsx example, so keep things in context. As for your multiple conditions question, what exactly is the point of that? All l see is code, no data, no markup. Completely irrelevant.
- bschwindHN 10y agoNo need to get so defensive. I'm just curious how it holds up in more complex examples. I know how JSX does because you just use the same concepts you already know from JS. But Mustache seems to have its own custom syntax, so how well can it express more complex cases? After all, we're not just displaying "Hello" or "Please log in" all day.
- 10y ago
- olegkikin 10y agoWow. Do people consider this kind of coding acceptable now? We spent decades trying to separate templates, business logic, and inlined JS, and you managed to cram all three into a short snippet.
- kentor 10y agoYes and this is a tired argument by now. The talk by Pete Hunt aptly titled "React: Rethinking best practices"[0] given in 2013 points out how separating templates and logic is merely a separation of technologies, not concerns. [0]: https://www.youtube.com/watch?v=x7cQ3mrcKaY https://www.youtube.com/watch?v=x7cQ3mrcKaY
- ggregoire 10y agoThanks for posting this, it was really interesting. Everyone who criticizes JSX should have watched it before doing so.
- EugeneOZ 10y agoAgree. Looks like those who haven't suffered from it, can't live without this suffer. They just need to have this experience to be able to understand downsides.
- madeofpalk 10y agoIt's actually no different to any other templating solution. Take a look at this[1] Mustache.js example and note the logic! At least JSX is honest about what it is. [1]: https://news.ycombinator.com/item?id=13153298 https://news.ycombinator.com/item?id=13153298
- orange8888 10y agoI guess honest can be a nice way of saying more verbose, just like elegant is another way of saying more terse and simple for those who get it
- deleted 10y ago[deleted]
- debaserab2 10y agoWhen I first started using React, I was very concerned about the lack of template support for conditionals. In practice, I've find that I now segregate heavy logic into it's own function, which ends up making my components very readable. The lack of first class support for conditionals as a part of JSX has forced me to encapsulate code better. I would say the only trade-off I've noticed is I end up losing a little bit of DRY-ness here and there with some components having near identical functions. I think it's an acceptable trade off as long as functions are small.
- mastazi 10y ago> and sound like "we couldn't figure out how to make it work for us so it must be impossible". It sounded more just like "we couldn't figure out how to make it work for us", which is a perfectly plausible position. The author just stated that React didn't work for them, not that it's "impossible to use React" as you are implying. From the article: > I guess this level of strictness and purity is something that may be useful when you have 1000 devs in your company [...] But most of companies have far smaller dev teams and other goals than Facebook.
- deleted 10y ago[deleted]
- guntars 10y agoFair enough, but if they're going to write about their opinions and argue that "JSX sucks", they should at least be intimately familiar with it. Choosing lack of conditionals as the issue to focus on instead of any other problems templating in React has tells me that they're not.
- andrewingram 10y agoFor the first example, if you're willing to risk a stage-0 transform, you could try using a shiny do expression: render() { return <div> {do { if (loggedIn) { <a>Logout</a>; } else { <form onSubmit={ ... } />; } }} </div> }