{"action":"created","issue":{"url":"https://api.github.com/repos/facebook/react/issues/690","labels_url":"https://api.github.com/repos/facebook/react/issues/690/labels{/name}","comments_url":"https://api.github.com/repos/facebook/react/issues/690/comments","events_url":"https://api.github.com/repos/facebook/react/issues/690/events","html_url":"https://github.com/facebook/react/issues/690","id":24672058,"number":690,"title":"JSX conditionals requires a lot of workarounds a lot of the time","user":{"login":"syranide","id":1714255,"avatar_url":"https://avatars.githubusercontent.com/u/1714255?v=3","gravatar_id":"","url":"https://api.github.com/users/syranide","html_url":"https://github.com/syranide","followers_url":"https://api.github.com/users/syranide/followers","following_url":"https://api.github.com/users/syranide/following{/other_user}","gists_url":"https://api.github.com/users/syranide/gists{/gist_id}","starred_url":"https://api.github.com/users/syranide/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/syranide/subscriptions","organizations_url":"https://api.github.com/users/syranide/orgs","repos_url":"https://api.github.com/users/syranide/repos","events_url":"https://api.github.com/users/syranide/events{/privacy}","received_events_url":"https://api.github.com/users/syranide/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":9,"created_at":"2013-12-21T22:25:56Z","updated_at":"2015-06-05T18:30:19Z","closed_at":"2013-12-21T23:03:24Z","body":"# The one good example\r\n\r\nConditionals are currently solved with the ternary `?:` or `&&` + `||` and actually works surprisingly well. However, what can be returned by them is another story.\r\n\r\nThe academic textbook example works great:\r\n\r\n```\r\n<div>\r\n  {condition ?\r\n    <span></span>\r\n  : null}\r\n</div>\r\n```\r\nor\r\n```\r\n<div>\r\n  {condition &&\r\n    <span></span>\r\n  }\r\n</div>\r\n```\r\n\r\nLooks pretty good, works great.\r\n\r\n# Any other is a disaster\r\n\r\nBut in order to return 2+ tags you need to return an array, which also requires that you separate them by commas (good bye beautiful JSX):\r\n\r\n```\r\n<div>\r\n  {condition ?\r\n    [\r\n      <span></span>,\r\n      <span></span>\r\n    ]\r\n  : null}\r\n</div>\r\n```\r\n\r\nIf you want a text-node instead then you have to actually rewrite your JSX-style code to pure JavaScript instead, which is perhaps even worse:\r\n\r\n```\r\n<div>\r\n  {condition ?\r\n    'My name is ' + name + '!'\r\n  : null}\r\n</div>\r\n```\r\n\r\nLet's also do the complete version, a text-node surrounded by tags, whitespace rules fly out the window and it no longer looks anything like JSX:\r\n\r\n```\r\n<div>\r\n  {condition ?\r\n    [\r\n      <span></span>,\r\n      'My name is ' + name + '!',\r\n      <span></span>\r\n    ]\r\n  : null}\r\n</div>\r\n```\r\n\r\nAnd while we're at it, if there are nested ifs then it looks like this, so let's go all out ugly, despite how simple it really should be:\r\n\r\n```\r\n<div>\r\n  {condition ?\r\n    [\r\n      (condition ?\r\n        [\r\n          <span></span>,\r\n          'My name is ' + name + '!',\r\n          <span></span>\r\n        ]\r\n      : null),\r\n      'Hello ' + name + '!'\r\n    ]\r\n  : null}\r\n</div>\r\n```\r\n\r\nThat is barely even understandable code. When without conditionals it would look like this:\r\n\r\n```\r\n<div>\r\n  <span></span>\r\n  My name is {name}!\r\n  <span></span>\r\n  Hello {name}!\r\n</div>\r\n```\r\n\r\nSo in my opinion, something is clearly wrong here, adding a conditionals should never require you to be working with arrays and rewriting inline text to use JavaScript string literals instead, or in general require you to massacre your code.\r\n\r\n# The problem(s)\r\n\r\n## Multiple tags\r\n\r\nThe easy part problem is simply that we currently cannot return more than one tag before having to resort to arrays. Intuitively this should be relatively easy to fix in JSX by simply automatically wrapping such as arrays. Simple, intuitive and good output?\r\n\r\n## Conditionals\r\n\r\nWhile it may not be a big deal, it's weird that the syntax for an if-statement `<tag>{cond ? true : false }</tag>` is different from a nested if `<tag>{cond ? (cond ? true : false) : false}</tag>` (braces replaced with parenthesis, because we're already in an expression) and it's back to braces if it's inside a tag `<tag>{cond ? <tag>{cond ? true : false}</tag> : false}</tag>`.\r\n\r\n## Text and expressions\r\n\r\nThe last big issue is that we can transition from JS to JSX-HTML by adding a root tag `<tag></tag>`, but we cannot transition directly to JSX-text and JSX-expressions `My name is {name}!` without it being wrapped in a tag `<tag>My name is {name}!</tag>` or without being rewritten to plain JavaScript `'My name is ' + name + '!'`. Which is necessary because conditionals are currently implemented as expressions.\r\n\r\n\r\n# Solutions\r\n\r\n## New conditional syntax\r\n\r\nSo it seems to me like the root of the problem is that conditionals are implemented as JSX expressions, which also causes the problem with having to rewrite JSX text/expressions when adding conditionals unless they are wrapped by tags. If they did not piggyback on JSX expressions then everything but non-parented JSX text/expressions would be solved, and really, that's not an issue at all.\r\n\r\n## Nesting of JSX expressions\r\n\r\nAnother solution is to allow JSX-expressions to be nested `<tag>{cond ? {cond ? true : false} : false}</tag>`, JSX text/expressions inside conditionals will still be a problem, but that could reasonably be solved by backtick strings ```<tag>{cond ? `My name is {name}!` : null}</tag>```.\r\n\r\n## Or...\r\n\r\nOr do you think there are better ways one should use to structure the code? Am I missing something?\r\n\r\nI realize that this perhaps is approaching it from the perspective of old-style templates, but from where I'm standing now, these things seem to make it quite cumbersome in more complex situations... there are a lot of situations in which one has to change surrounding code simply because one added a tag, or because one removed a tag... or moved a conditional.\r\n\r\nPS. We had some discussion in the chat, and I agree that most of this is probably just \"old-school template habits\", however, returning multiple tags is biting me in the ass a lot. While everything content inside conditionals could be wrapped in divs/spans to make it play nice, it seems weird to have to add markup just to be able to write reasonable JSX.\r\n"},"comment":{"url":"https://api.github.com/repos/facebook/react/issues/comments/109388905","html_url":"https://github.com/facebook/react/issues/690#issuecomment-109388905","issue_url":"https://api.github.com/repos/facebook/react/issues/690","id":109388905,"user":{"login":"jquense","id":339286,"avatar_url":"https://avatars.githubusercontent.com/u/339286?v=3","gravatar_id":"","url":"https://api.github.com/users/jquense","html_url":"https://github.com/jquense","followers_url":"https://api.github.com/users/jquense/followers","following_url":"https://api.github.com/users/jquense/following{/other_user}","gists_url":"https://api.github.com/users/jquense/gists{/gist_id}","starred_url":"https://api.github.com/users/jquense/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jquense/subscriptions","organizations_url":"https://api.github.com/users/jquense/orgs","repos_url":"https://api.github.com/users/jquense/repos","events_url":"https://api.github.com/users/jquense/events{/privacy}","received_events_url":"https://api.github.com/users/jquense/received_events","type":"User","site_admin":false},"created_at":"2015-06-05T18:30:19Z","updated_at":"2015-06-05T18:30:19Z","body":"If anyone is annoyed by this as I was and uses babel, I wrote a plugin to implement (in part) the `<frag>` syntax mentioned above.\r\n\r\nhttps://github.com/jquense/babel-plugin-jsx-fragment"}}