8 ms·
I like how the if proposal is down voted, probably because it's mentioning Angular. Conditional rendering in React is not always very clean. Most codebases end
by maaaats 10y ago
I like how the if proposal is down voted, probably because it's mentioning Angular. Conditional rendering in React is not always very clean. Most codebases end up resorting with something similar to this in a container to show a spinner while data is loading and rendering it when done.
<ConditionalSpinner renderIf={data}><PersonRenderer person={data.person} /></ConditionalSpinner>
Problem is that the inner component will still be parsed and fail with cannot read property person of undefined. Yes, you can do this with a simple condition in your render function, but then it's not declarative any more.
- doque 10y agoHow about { data && <Inner person={ data.person }/> } ?
- ponyous 10y agoIf you render a more complex component this introduces another level of indentation. I can see why some people would prefer cleaner code but in my opinion, indenting ifs is a good thing as it increases the readability and allows you to spot if statements faster.
- zackify 10y agothis is why you should be using immutable js. It will not throw errors accessing an object.
- deleted 10y ago[deleted]
- deleted 10y ago[deleted]
- msoad 10y agoIt's the extreme fanboyism there! Wrapping every component that has `if` attribute with an `if` statement should not result into that: <div *if={cond1 && cond2}> <div>foo</div> </div> // results to if (cond1 && cond2) { return React.createElement('div', null, React.createElement('div', null, 'foo') ); } I'm not sure why this is bad? Because it's looking like Angular?!!
- cel1ne 10y agoI think ternary expression are rather ok here, though not perfect: {cond1 && cond2 ? <div>foo</div> : null }
- danneu 10y agoAnd you can inline if-statements with an IIFE when you need a little more space: {(() => { if (cond1 && cond2) return <div>foo</div> else ... })()} Though it makes GitHub think it's a Clojure file.
- vanderZwan 10y ago{(() => { })()} Honestly I can't decide if I think this is ugly or beautiful. It's like the buffalo buffalo of JS.
- olalonde 10y agoThat's something the "do expressions" ECMAScript proposal is meant to solve: {do { if (cond1 && cond2) <div>foo</div> else ... }} If JSX decides to implement "implicit" "do expressions", I suppose it would just look like this: { if (cond1 && cond2) <div>foo</div> else ... } http://wiki.ecmascript.org/doku.php?id=strawman:do_expressions http://wiki.ecmascript.org/doku.php?id=strawman:do_expressio...
- deleted 10y ago[deleted]
- spirit23 10y agoIt’s interesting to see that there are so many ways of doing conditions in JSX. I myself wrote a tiny library (http://github.com/yuanchuan/cond http://github.com/yuanchuan/cond) for it several months ago and thought it made the code looks clean but suffers the same undefined issue though.
- 10y ago
- coderzach 10y agoNow that sweet.js supports babel, the best option may be to write an if expression macro.
- Marazan 10y agoThe Flex method of conditional rendering is nice, far better than ng-if all over the place.
- biscarch 10y agoLoading (and error, etc) state should be the responsibility of the component doing the content rendering, not the parent. So the ConditionalSpinner component: <ConditionalSpinner renderIf={data}><PersonRenderer person={data.person} /></ConditionalSpinner> Could be written better as: <PersonRenderer person={data.person} /> Where PersonRenderer would be defined as such: class PersonRenderer extends Component { render() { if(this.props.person) { return <div>personcontent</div> } return <LoadingIndicator/> } } Given this, I'm still not sure how an If "component" would be achieved (and further, you'd need an Else or a Switch component anyway if going down this route). Maybe you could explain the benefits of such a path?
- maaaats 10y ago> Loading (and error, etc) state should be the responsibility of the component doing the content rendering It's often divided in two: One container fetching the data, and a pure component rendering it.
- biscarch 10y agoI think my intent might have come across wrong here. The "states" aren't related to container/dumb components or data-fetching/selection logic. They're purely about rendering the state for a given segment of the page. Perhaps this article[0] might help convey my intent. It's more about how to render "we didn't get data from that one endpoint for this section of the page" or "we're waiting for the data to show up", etc. [0]: https://medium.com/swlh/the-nine-states-of-design-5bfe9b3d6d85 https://medium.com/swlh/the-nine-states-of-design-5bfe9b3d6d...
- snappy173 10y agoor create a wrapper function ... function withLoadingIndicator(Wrapped) { return function(props) { if (props.loading) { return (<LoadingIndicator />); } return (<Wrapped {...props} />); } } // ... export class PersonRenderer extends Component { render() { return <div>personcontent</div> } } export default withLoadingIndicator(PersonRenderer);
- spdustin 10y agoJSX shouldn't be used to turn a component into a controller for child components. That's why I wouldn't want that kind of logic in there.
- woah 10y agoYou think it's downvoted because it mentions Angular? Baseless complaining. JSX is a breath of fresh air after all the templating languages that force you to learn a crippled pseudolang. What's next? For loops? Moving every feature that already exists in JavaScript into JSX with some arbitrary additional syntax? What's the point? It's already very easy to do conditionals with && or ternaries.
- tracker1 10y agoYou can already do that... function ConditionalSpinner({renderIf, children}) { if (!renderIf) return null; return children[0]; }
- inimino 10y agoIn what sense is it not declarative anymore? I usually use tests at the top of the render function to make sure that data is there, and return cleanly if it isn't. It just makes development easier as React components tend to get re-used. Within the data.person, in your example, the caller should make sure that it is complete, or pass nothing at all. In the case you show I would either return <Spinner/> or the content, but never nest them. Have a conditional and two return statements, or one return statement with a ternary operator.
- hdra 10y agoI down voted that proposal as well, but not because the mention of Angular, but because I don't like the `ng-if` way of doing conditionals. One of the reason I like JSX is because it is "just Javascript". Putting the flow control logic into component attributes like that is a terrible idea for JSX.
- buchanaf 10y agoI actually generally include this in my Babel configuration: https://www.npmjs.com/package/jsx-control-statements https://www.npmjs.com/package/jsx-control-statements. People might argue that this isn't the React way of doing things, but it's easier than setting a conditional classname to display none. It's also easier than breaking out a small amount of html into a separate component just because you want some conditional display logic.