top | item 45861472

(no title)

erikpukinskis | 3 months ago

I mean, you’re technically correct. But you’re also not understanding the point.

What people mean when they say “React is just JavaScript” is…

1) JSX, more than any other templating system, is just HTML interleaved with JavaScript. It’s HTML, and anything between { and } is evaluated as JavaScript.

2) Inserting a React component’s “HTML tag” in your JSX is _actually_ the same as calling the JavaScript function. The HTML attributes are the function arguments. Yes, inside your function there can be state, and there can be contexts, and there are refs. But you get at all of those things by calling JavaScript functions.

Like,

      <b><MyComponent attr=“yes” /></b>
is literally identical to:

      <b>{MyComponent({ attr: “yes” })}</b>
It’s the tiniest bit of syntactic sugar.

I feel like too many people think “React is Just JavaScript” is some kind of lie people tell to make React sound cool.

It’s not a lie. There’s a _small_ amount of hand waving around the word “just” but the point is, it’s WAY smaller than what you need to explain the ways Svelte or Vue or Angular diverge from plain JavaScript.

discuss

order

MrJohz|3 months ago

It's further than that even. JSX has the semantics of (modulo a couple of optimisations there and there) a bunch of nested function calls returning normal JavaScript objects. That means you can, in your head, very easily convert between the JSX representation of an expression and the equivalent transpiled JavaScript code.

This is unlike a lot of other templating languages where, even if the expression part of the language is pure JavaScript (or PHP or Python or whatever), it's still interleaved with arbitrary text which will get printed out according to its own rules. This makes the whole thing much harder to reason about (leading to the philosophy that you should put as little logic as possible in your templates because it makes them harder to understand, _even when that logic is directly related to the templating process_.

A good example is for-loops. In a lot of templating languages, you start in text-land, then you enter expression-land to write the opening {% for (const X of ...) %} line, then you're back in text-land again. You sprinkle in a couple of expressions, and then at the end you go back to expression-land to close the loop. You're jumping backwards and forwards between the two worlds, but there's no real syntactical or structural support for mixing them.

Meanwhile, in JSX, you start in text-land, then you open up an expression between two curly braces, and in that expression you write the entirety of your loop. If you need to go back to text-land within that loop, you can create a _new_ set of text nodes, but you're not interleaving expressions and text in the same way.

The result of this is that, once you understand how your JSX will get compiled, it's very easy to read it as if it were the JavaScript that it will get compiled to, rather than as a separate templating language. Which in turn makes it very easy to think of it as "just JavaScript", even if it's technically a syntax extension.

csande17|3 months ago

I don't think the syntactic sugar works how you describe. JSX components actually desugar to something like:

   <b>{jsx(MyComponent, { attr: "yes" })</b>
(Previously this function was called "React.createElement", but these days they have special functions that only the JSX compiler is allowed to use.) The extra layer of indirection is needed to do things like support hooks being called inside of MyComponent's function body, keep track of `key` props, and so on.

samdoesnothing|3 months ago

I don't think that's true, you can write uncompiled createElement calls and everything still works fine.

afavour|3 months ago

> JSX, more than any other templating system, is just HTML interleaved with JavaScript. It’s HTML, and anything between { and } is evaluated as JavaScript.

That’s not true though and IMO is one of the weaknesses of JSX: it looks like something it is not. Having to use className instead of class is one of the most obvious tells. But in theory if it was just HTML with {}s I should be able to do:

    <{tagName} />

    <span {someStringWithAttributes} />

    <div>{stringContainingHTML}</div>
and many other things you’re actually not able to do. Not to mention that things like onClick aren’t actually HTML attributes and are instead event listeners, etc etc.

Once you grasp that what you’re actually doing is a function call with an object of arguments it makes sense. But it isn’t HTML. It’s a chain of function calls.

We’re all really used to it so we don’t think about it a lot. But I always try to remind myself of that when I look at a new unfamiliar syntax.

(not to mention, your example isn’t correct! <Component/> don’t map to Component(), it maps to previouslyUnknownFunction(Component()), which is another confusing factor)

christophilus|3 months ago

You can just use “class”, fyi, at least in Preact, and iirc, it works in React, but isn’t officially supported there.

dminik|3 months ago

And this is one of the disadvantages of JSX. The snippets you posted are NOT identical.

JSX (react flavor) is lazy. <My component> is not rendered/evaluated until it's needed.

You can't just call a react component. It's not a regular function call.

zaidf|3 months ago

It’s not JavaScript if you can’t make an html page locally and open it in your browser without things like an http server or need to transpile.