You can get around it with a Babel transform:
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 :(.
The article doesn't bash react, but it does say that Vue's ability to use conditionals is superior.
Wrapping 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` }
/>
}Or 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:
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.