4 ms·
This. Most of the value-proposition of JSX is that it is just JavaScript and as such you just write code logic like you would normally do. Need to filter some i
by snorremd 3y ago
This. Most of the value-proposition of JSX is that it is just JavaScript and as such you just write code logic like you would normally do. Need to filter some items? You can do that with the Array.prototype.filter method you already know. Do you need to return a list of components based on some list of object values? Just use Array.prototype.map.
I never really understood those that see this as a weakness and would rather learn a more limited set of template string functions that work kind of like, but not entirely like, the native JavaScript collection functions.
Yes, using a ternary operator in JSX to conditionally render components/values looks a bit ugly, but nothing is stopping you from making a wrapper component like:
<If cond={...}><div>Conditional content</div></If>.
Also with JSX/TSX scopes behave exactly like they do in regular JavaScript, because it is regular JavaScript. Templating languages often invent their own form of scoping mechanism.
- jcparkyn 3y ago> nothing is stopping you from making a wrapper component like... I'd suggest avoiding that, since the inner JX expression will be evaluated even if cond is false. In the best case this just means some unnecessary allocations, but in other cases it can cause unexpected errors (e.g. you check obj != null then try to use it inside the if).
- jpochtar 3y agoYeah you have to do <If cond={...} then={() => ... } els={() => ... } /> so the `then` and `els` branches only get evaluated if needed
- mbork_pl 3y agoEven though I'm a JS programmer myself and I do use similar constructs once in a while, I have to admit that this gets dangerously close to the Greenspun's tenth rule... In times like this I miss proper Lisp macros.
- gdprrrr 3y agoWhich has ugly untax IMO
- SkyPuncher 3y agoWe use ternary extensively with in JSX. Keeps the logic in vanilla JS { some_condition ? ( <H2>It was true</H2> ) : ( <H2>It was false</H2> )
- snorremd 3y agoGood point. You'd have to pass the stuff to be rendered as a function that would be run if the conditional is true. In any case you just add another allocation, scope (the anonymous function), etc. But some people might like the "syntax" a bit better.
- mmis1000 3y ago> ... the inner JX expression will be evaluated even if cond is false. Well, actually. it don't have to be. Just React decides to compile JSX in that way. Vue 3 also supports JSX. But it keep the content of children lazily evaluated. Their compiler compile a JSX `<Parent><Child /></Parent>` to structure like `h(Parent, {}, { default: () => h(Child, {}, {}) })` . So the child jsx tag is never evaluated unless the Parent component want to. It's really not a syntax limitation because JSX never specify that the children of element must be eagerly evaluated.
- jameshart 3y ago> It's really not a syntax limitation because JSX never specify that the children of element must be eagerly evaluated. That seems like a dangerous reinterpretation of JSX. It's just a literal syntax, it's not meant to be lazily evaluated. Having a JSX compiler interpret <Parent><Child /></Parent> as h(Parent, {}, { default: () => h(Child, {}, {}) }) would be like having a JS compiler interpret let parent = { child: {} }; as let parent = {}; Object.defineProperty(parent, 'child', { get: () => ({}) }) That's just... not what that syntax means. It should be h(Parent, {}, [ h(Child, {}, []) ]) Saying 'JSX doesn't specify it' feels like playing a 'there's no rule that says a dog can't play basketball' card.
- mmis1000 3y agoIt's a framework specific DSL anyway. (Unlike e4x, which is actually a standardized feature). There isn't a spec decides how it must be interpreted. And it also don't matter as long as the specific framework that use jsx output standard javascript that browser can understand. In practice, every framework interpret jsx in slightly different way. React has own. Vue has own. Solid has own. And even react itself interpret JSX in 2 way (the new and old jsx compiler). So I feel there really isn't a rule that you can't compile jsx in some specific way because the output is never part of the specification of jsx from the beginning.
- jcparkyn 3y agoInteresting, I haven't used Vue so I wasn't aware that some frameworks do it differently.
- nonethewiser 3y ago> Yes, using a ternary operator in JSX to conditionally render components/values looks a bit ugly, but nothing is stopping you from making a wrapper component like: Couldn't you put that in a function that returns the correct JSX element or am I misunderstanding the problem? Something like: renderThing(number) { if(number > 0) return <div>...</div> return <div>...</div> } const Page = () => { return <div>{renderThing(someNumber)}</div> } Simple ternaries are fine IMO but thats what I do when the logic gets complicated. I never used a nested ternary in that situation, for example.
- kwkelly 3y agoYou have to be careful with code like the above in React. Using a lower-cased function that returns JSX but is not rendered with react.createElement (either directly or via the JSX syntax) can lead to confusing violations of the rules of hooks as it relates to exact ordering of calls. This is because it doesn't get registered as it's own component, so conditionally called children with hooks may cause errors.
- aabbcc1241 3y agoThe render function is a pure function returning jsx based on the input, not invoking any stateful operation like "functional hook". So this style of code is fine in react
- nonethewiser 3y agoDoes simply uppercasing it avoid these concerns?