Why are text nodes in jsx interpreted as symbols?

I don’t get it. How do you get a runtime error by treating strings between tags as actual strings?

I think measuring forum activity as a gauge of community consensus is a mistake–my experience has been people are busy building with ReScript and may not necessarily check in all the time.

Absolutely. Sorry, my comment was a bit of a provocation but all I meant was: I feel strongly about this, and I’m glad I’m not the only one.

It isn’t really a change to JSX syntax

I don’t really understand your claim. In React…

function HelloWorld () {
  const hello = 'hi there'
  return <div>hello</div>
}

…will output <div>hello</div>, whereas in Rescript…

@react.component
let make = () => {
  let hello = React.string("hi there")
  <div>hello</div>
}

will output <div>hi there</div>. In React you need <div>{hello}</div> for it to be a variable reference. In React <div>hi there</div> will output just that; in Rescript it’s a syntax error. That’s the syntax change I’m complaining about.

Your AST screenshots seem to support this? In the first example {children} is a JSXExpressionContainer and in the second Hello is a JSXText.

Earlier I was claiming that it’s the only syntax change in resx compared to jsx, but of course that’s not the case. There’s the fact that <Thing value={value} /> in jsx becomes <Thing value /> in resx, while <Thing enabled /> in jsx becomes <Thing enabled={true} /> in resx. And I welcome that tweak, I do think it’s a bit nicer.

I wonder how much there’s a European bias thinking that pretty much any app has to use i16n at some point.

I don’t have strong opinions about all this, but I guess it would lower the barrier for newcomers to be able to just copy paste code from JS/TS.

We could make the formatter print curly brackets around variables first, then start introducing a syntax sugar that wraps characters between tags in a React.string. But I might totally overlook crucial things here.

4 Likes

I do agree this is muuuch nicer compared to JS/TS. The whole thing about payload-less attributes in HTML/JSX is very ugly.

1 Like

Pragmatically, the approach you suggest might be the best way to go, but my vote would be for no extra syntax sugar, just a breaking change to the syntax. I realise it would be a significant breaking change though.

I don’t think it’s just a convenience thing of “being able to dump HTML code in”, it’s fair bit of headache for readability and has an impact on correctness to have to break up strings and get the spacing right, as per my example in the OP.

3 Likes

I think if we do it step by step as @tsnobip said, by starting wrapping the variables in curly brackets. Then later it’ll be easier to add an ability to pass plain text.

2 Likes

what do you mean no syntax sugar? Down the line, semantic-wise, the text has to be of type React.element, so it has to be wrapped inside a React.string. What’s wrong with a syntax sugar? What would you replace it with?

Well I mean, JSX is itself nothing but syntax sugar, but I meant I don’t think we want to do anything extra to allow variable references outside braces and text nodes. Probably I misunderstood you.

Any child of a node in JSX (ie. any text inside a tag) which isn’t itself a tag or in expression braces, should unambiguously become a text node. That’s what we’re talking about, right?

3 Likes

Yes exactly, by syntax sugar I mean we would not need to explicitly call React.string anymore.

2 Likes

You actually made 3 nodes implicitly on here "You've clicked it ", count, " times!"

They are intepreted as text nodes in React DOM. As a result the spacing of the message is not preserved properly. So you eventually change it to You've clicked it ${count) times! or add the white-space: pre style.

This is actually a chronic problem with the React.ReactNode type in regular JSX, which is never happened in ReScript JSX.

(Have you ever seen a dangling "0" string appear somewhere in an app built with React? Same problem)

1 Like

The suggested solution shouldn’t have the problem. The white-space: pre is a valid point, but I think it’s worth sacrificing.

I’ve been using Rescript for a long time, and I have to say besides my initial “meh” it wasn’t an issue.
Here is a small tip I use:

let s = React.string

<p>{"Hello world!" -> s}</p>

Of course, there is room for improvement, but Rescript already is awesome, and I think string in JSX won’t be the biggest deal breaker for Typescript hardheads who want to replicate Java patterns in Rescript. The biggest Rescript appeal is it comes from the Ocaml family, not Java :wink:

2 Likes