It is not just about JSX, it is a JavaScript limitation that affects JSX.
In JavaScript, a function can only return one expression by design, for example:
function textJoin(text, txt){
return `${text} ${txt}`;
}
console.log(textJoin('this', 'is'))// returns and logs `this is`
if we were to say:
...
return text
return txt
...
or
return text, txt
We will encounter that the first one will only read the first return and the second one will only return the last value (txt), yet if we get rid of the comma we will encounter an error: SyntaxError: Unexpected token, expected ;
Since JSX is still JavaScript, its return can only handle one expression therefore to return more than one element we need to wrap it in another (an outer element), which most commonly will be a <div></div>.
I think it’s not about the limitation of the function return, it’s all about how our JSX code is compiled.
Under the hood JSX is compiled to React.createElement() and understanding how it works will tell us why we have to have only one outer.
assume this jsx tag: <h1 className="myClass">Hello</h1>
it will be compiled under the hood to React.createElement( 'h1', {className: 'myClass'}, 'Hello' );
we are passing the tag name to the first argument and that’s it we can’t pass more than one tag to the first argument, that’s why we need to have only one outer so it can get compiled to React.createElement.
=================================================
and sure you can use React.createElement directly but it will be too much code, that’s why they made this syntactic sugar JSX.
and by the way, that’s also why our JSX code can’t work if we didn’t import React.