Why are text nodes in jsx interpreted as symbols?

In javascript, <span>Hello world!</span> is a jsx value specifying a span element with a text node as a child; <span>Hello {place}!<span> interpolates a variable into that text node.

In rescript, <span>Hello world!</span> is a syntax error, and <span>greeting</span> works as long as greeting is a variable containing a React.element. This reversal would maybe make sense to me if I could also do <span>toGreeting(place)</span> or some other expression, but it seems the only thing allowable in that position without enclosing braces is a bare symbol.

This makes me wonder why the jsx syntax has this variation in rescript compared to javascript. What motivates this? I don’t think it’s some demand of the type system, since as far as I can think of, text nodes would trivially compile to React.strings. I also can’t think how it could be problematic syntactically.

For me, one of the advantages of jsx/HTMl templating is being able to write things like <span>This is an <em>important</em> message</span>, whereas in Elm, Halogen, or any other framework where VDOM values are built with regular function calls, you have the additional annoyance of chopping it up into text nodes and an em element. This same annoyance comes up in rescript’s jsx where I have to do <span>{React.string("This is an ")}<em>{React.string("important")}</em>{React.string(" message")}</span>, thinking very carefully about the spacing in the strings.

1 Like