JSX violates referential transparency

I’ve put my finger on what I most dislike about JSX: it violates referential transparency.

We should be able to replace a variable with the expression we evaluated to determine its value. f (y + z) should be equivalent to f (x) if x = y + z.

This is not the case in JSX. Consider this code:

const Foo = f (x);
return <Foo bar={42} />;

We cannot replace Foo with f (x).

Here’s the equivalent code written with React.createElement:

const Foo = f (x);
return React.createElement (Foo, {bar: 42});

Obviously we can replace Foo with f (x) in this case:

return React.createElement (f (x), {bar: 42});

JSX is less expressive than the underlying JavaScript API. It violates an important property of functional programming, and highlights the inherent complexity of syntax.