6 ms·
When I was first introduced to JSX I found it very confusing because it was sold to me as "HTML in Javascript" but it's... really not. In particular these thing
by awirth 8y ago
When I was first introduced to JSX I found it very confusing because it was sold to me as "HTML in Javascript" but it's... really not. In particular these things threw me off:
- You need to close tags you wouldn't need to close in HTML (breaks copy+pasted HTML)
- Argument quoting isn't optional (breaks copy+pasted HTML)
- HTML style Comments aren't allowed (breaks copy+pasted HTML)
- Whitespace gets stripped for all elements (breaks PREs)
- There's a JSX-specific syntax for "fragments" that seem to only exist for parser reasons?
- Variable references work inside of text nodes but don't inside of attributes.
After I googled a bunch and read the spec it helped a bit, but it left a bit of a bad taste in my mouth. I'm still left scratching my head over why you should be able to use an element as the value for an attribute though, like this:
<foo a=<bar> test </bar>/>
- wereHamster 8y agoElements as values of attributes are extremely useful in custom components. <FancyArticle heading={<h1>...</h1>} body={<main>...</main>} />
- sametmax 8y agoOther systems address that by providing a <template>, # include or {% block %} element that allow you to state where/what things should be inserted. I dislike the attribute way because: - attributes are used for everything. It seems nice and simple - one single way to do all things ! - but it means when you see something passed this way, you never know what it's for without diving into the code or doc. There is no convention. Is it data ? Is it a children ? Is it a callback ? If yes, what for ? - it allows people to make big inline blobs of code. And as often, when something ugly is easy on the short run, and the clean things is hard, they do the easy thing. JS is full of those stuff, and I wish we would not add new ones in the tooling we use. - The syntax is so unatural when you have been doing HTML for decades. I understand the desire not to be limited by legacy, but here it's not working around any limit. There are alternatives. So we just break habits to break habits. Again something quite common in modern JS: let's replace the wheel by a different one. Not better. Just different. Because, reasons. - It's easy to get wrong. Case in point, your comment and the parent don't even have the same syntax because one of you couldn't, from the top of the head, come up with the proper one.
- pault 8y agoI personally have never passed a JSX element through an attribute, and I don't see what the use case would be. It smells like an anti-pattern. Why wouldn't you use a render function that returns an element, or just pass the component and create the element in the child?
- tracker1 8y agoThe places I see it the most are in routing and access control components. Here's a convoluted example in my router, not common throughout the application. <Route path="/petition/:petitionId/page/next" render={({ match }) => ( <InRoles roles={Roles.pageReviewer} deny={`/`} allow={PS(match.params.petitionId, SECTION.PAGES, null, ({ petitionId }) => ( <PageReviewNextPage petition={petitionId} page={'-'} direction={1} /> ))} /> )} /> Route comes from react-router. InRoles is internal to the application and accepts a string or function/component... if it's a string it redirects as appropriate, or renders. if null/empty just hides the result. PS is a function that returns a nested/common component structure. A more simple example would be... <Fragment> <Switch> <Route exact path="/" render={({ location }) => <Home search={location.search} />} />
- awirth 8y ago"Case in point, your comment and the parent don't even have the same syntax because one of you couldn't, from the top of the head, come up with the proper one." I'm not sure what you mean by this. They're both valid. I don't find the one enclosed in {} nearly as confusing, because once you're inside curly braces you can have arbitrary javascript expressions so all bets are off. The thing that's strange is being able to have a JSX Element as an attribute value without enclosing curly braces. Perhaps the use case of passing arguments to custom elements is more common than I thought thought. Specifically "<foo a=<bar/>/>" is weird.
- JonathonW 8y agoFWIW, I've never actually seen that in real-world React code-- neither in libraries I've used, nor in my own code. It's more common (and much more natural) to see JSX Elements passed as children to other components, like you see with a react-bootstrap Panel, for example: <Panel> <Panel.Heading>Foobar</Panel.Heading> <Panel.Body> Panel body contents </Panel.Body> <Panel> Which is itself just passing the Panel.Heading and Panel.Body elements as an array to Panel's children prop, but it's much more natural than having some arbitrarily complex hierarchy of elements passed in another prop.
- Zarel 8y agoThe "X" stands for "XML", and these things are all XML: - You need to close tags you wouldn't need to close in HTML (breaks copy+pasted HTML) - Argument quoting isn't optional (breaks copy+pasted HTML) - HTML style Comments aren't allowed (breaks copy+pasted HTML) - Whitespace gets stripped for all elements (breaks PREs) JSX is based on XML rather than HTML because XML is a version of HTML with all the backwards-compatibility weirdness stripped out, which makes it easier to parse. If you've learned XHTML, JSX isn't very hard. The stuff about <pre> elements and elements as values are pretty easy if you remember that all attributes are just JavaScript values, and the contents of a JSX element is just the "children" attribute. In other words, these are the same: <foo>{bar}</foo> <foo children={bar} /> And `bar` is just a JavaScript value - a JSX fragment, a string, a number, whatever you want it to be.
- _pmf_ 8y ago3. and 4. are valid in XML.
- Zarel 8y agoOh, huh, I didn't know XML uses the same comments as HTML. 4 is valid, though: XML requires special directives to preserve whitespace. JSX requires different syntax with {`...`}, but it's a similar idea.
- _pmf_ 8y ago> XML requires special directives to preserve whitespace Not in what you would consider content: from http://usingxml.com/Basics/XmlSpace http://usingxml.com/Basics/XmlSpace: "White space in any other location must be passed on to the processing application, according to the XML specification."
- IgorPartola 8y agoI don’t really care how easy it is to parse for a machine. I want it to be easy to parse for me. And HTML5 is plenty easy. GP is right, JSX is a weird bastard child of two languages that is very awkward.
- brlewis 8y agoNot sure what toolchain you're using. I'm using the typescript compiler with Mithril and whitespace is preserved for this code: <pre class="debug">{JSON.stringify(store, null, 4)}</pre>
- awirth 8y agoThat's different than preserving: <pre> foo</pre>
- dunham 8y agoI think they are referring to literal text/whitespace in the template. I don't know about other implementations, but typescript mutates the whitespace if newlines are involved. It seems that the rules are, for any run of literal text: - preserve runs of whitespace that don't contain newlines - drop initial and final whitespace if it contains a newline - collapse any internal runs of whitespace containing newlines to a single space. (based on a quick experiment with tsc.)