The obvious approach is… kinda obvious. But it gives you a hint to approach number two. Given that JSX compiles to JavaScript, there must be a pure JavaScript way to do the same thing. And while there’s a good chance that you already know the corresponding vanilla JavaScript, if you don’t, you can find out by clicking on the Compiled button in the above editor.

And if you do click on the Compiled button, you’ll see a couple calls to…

JSX elements in a React project are transformed at build time into calls to React.createElement(). This function’s first two arguments represent the elment’s type and props, while any subsequent arguments represent the element’s child nodes.

React.createElement(
type,
props,// You can pass as many children as you need - or none at all.
childNode1,
childNode2,)

For example, the two elements in the above JSX transpile to two separate calls to React.createElement():

There are three important things to understand about React.createElement():

It returns a plain old JavaScript object that contains all of the information that you passed into it.

It’s first two arguments represent type and props, and any further arguments represent its children.

You can pass as many children as you’d like… or none at all.

Simple, huh? But there’s one curious thing about the object returned by React.createElement(). While the returned object has properties corresponding to the type and props arguments, it doesn’t have a children property. Instead, the children are stored on props.children.

As you can see in the above editor’s console, the children prop is ignored in favor of the value passed via argument — which happens to be undefined. But this raises a question: what would happen if you didn’t pass a third argument?

This has an interesting corollary: you can also pass elements via props other than children. In fact, you can pass multiple elements to a component using multiple props. This pattern is sometimes called slots — and you can learn more about it with Dave Ceddia’s guide to slots.

Of course, you don’t have to use raw JavaScript to pass a children prop — which leads to the 4th and final way to specify an element’s children…

Putting aside the question of whether you can pass children via props(you can), let’s ask a perhaps more important question: should you?

It goes without saying that usually, it’s clearer to specify a JSX element’s children the standard way. But with that said, there are a couple situations where the ability to specify children as a prop comes in handy.

When working with React context, you’ll run into a small problem when you need to consume values from multiple contexts: you need to nest context consumers within each other to access multiple values. And so just when you thought that Promises and async/await had banished callback pyramids from the idyllic land of JavaScript forever, you end up with this:

You’ll notice that each calls to createElement() in the above example only uses two arguments, so any value for props.children will be passed through to <InvoiceScreenImpl>.

When you think about this, it makes a lot of sense. It would be confusing to have to specifically pass the children prop through. And luckily, you don’t have to — because React lets you specify children in an appropriate way for the situation!