What is JSX?
You may use it every day, but have you seen what happens after Babel transpiles it?
I think a critical part of understanding how to use React effectively is understanding JavaScript and JavaScript expressions. So I’m going to show you a few examples of JSX and it’s transpiled version to help give you an idea of how this all works. As soon as you can transpile JSX in your head, you can use the abstraction more powerfully.
Here’s our simplest example:
<div id="root">Hello world</div>; React.createElement("div", { id: "root" }, "Hello world");
As shown above, the JSX is transpiled to React.createElement
. The API to React.createElement
is:
function createElement(elementType, props, ...children) {}
elementType
can be a string or a function (class) for the type of element to be createdprops
is an object for the props we want applied to the element (ornull
if we specify no props)...children
is all the children we want applied to the element too. This is just a convenience and we could write an equivalent to above with:
React.createElement("div", { id: "root", children: "Hello world" });
If you have more than one child then you use an array:
<div><span>Hello</span> <span>World</span></div>; React.createElement("div", { children: [ React.createElement("span", null, "Hello"), " ", React.createElement("span", null, "World") ] }); // Note: babel uses the third argument for children: React.createElement( "div", // type null, // props // children are the rest: React.createElement("span", null, "Hello"), " ", React.createElement("span", null, "World") );
What you get back from a React.createElement
call is actually a simple object:
// <div id="root">Hello world</div> { type: "div", key: null, ref: null, props: { id: "root", children: "Hello world" }, _owner: null, _store: {} };
When you pass an object like that to ReactDOM.render
or any other renderer, it’s the renderer’s job to interpret that element object and create DOM nodes or whatever else out of it. Neat right?!
Here are a few more examples for you:
<div>Hello {subject}</div>; React.createElement("div", null, "Hello ", subject); <div>{greeting} {subject}</div>; React.createElement("div", null, greeting, " ", subject); <button =="" onclick="{()"> {}}>click me</button>; React.createElement("button", { onClick: () => {} }, "click me"); <div>{error ? <span>{error}</span> : <span>good to go</span>}</div>; React.createElement( "div", null, error ? React.createElement("span", null, error) : React.createElement("span", null, "good to go") ); <div>{items.map(i => <span key="{i.id}">{i.content}</span>)}</div>; React.createElement( "div", null, items.map(i => React.createElement("span", { key: i.id }, i.content)) );
Notice that whatever you put inside {
and }
is left alone. This is called an interpolation and allows you to dynamically inject variables into the values of props and children. Because of the way this works, the contents of an interpolation must be JavaScript expressions because they’re essentially the right hand of an object assignment or used as an argument to a function call.
Conclusion
If you’d like to play around with this some more, you can try online with Babel’s online REPL. Start here. Hopefully this helps you understand a little more about how JSX works and how you can use it more effectively. Good luck!
Looking for a job? Looking for a developer? Check out my job board: kcd.im/jobs
Learn more about React from me:
Things to not miss:
- “Headless User Interface Components - “A headless user interface component is a component that offers maximum visual flexibility by providing no interface. “Wait for a second, are you advocating a user interface pattern that doesn’t have a user interface?” Yes. That is exactly what I’m advocating.” Brilliant article by my friend Merrick Christensen.
- vscode-go-to-file - A plugin that aims to replicate some of Vim’s “go to file” (
gf
) functionality by the great Jack Franklin - tabb - A Chrome extension to search, save, and manage your tabs, history, and bookmarks written in Reason by my friend Ethan Godt
- deps-report - Generate reports about dependencies and dependents of your JavaScript/TypeScript files through an AST. It supports import and require statements. By the insightful Lorenzo Pichilli.
Some tweets from this last week:
> 🔥 I do this all the time. It’s pretty handy! Use .filter(Boolean) on an array and you can make your code much easier to follow via JavaScript expressions (like ternaries). – 21 Jun 2018
> I don’t know whether to laugh or cry @colepatrickturner > > https://github.com/coleturner/pettier/blob/master/index.js – 22 Jun 2018
> Dude, it’s so good. When you hold your own baby in your arms, it changes you. You have a whole new perspective on the world and your capacity to love and experience joy is increased by a huge measure. Teaching and loving my four small children is the best. – 24 Jun 2018
This last tweet started a huge thread about how great it is to have kids :)
This week’s blog post is “JavaScript default parameters”. It’s the published version of my newsletter from 2 weeks ago. If you thought it was good, go ahead and give it some claps (👏x50) and a retweet:
Special thanks to my sponsor Patreons: Hashnode
Extra special shoutout to Hashnode because I failed to include them last week:
> Hashnode is a platform built and optimized for developers by developers. You can ask, answer, write story, share and discover links there. Hmm… You can place us somewhere between Quora and StackOverflow.
P.S. If you like this, make sure to subscribe, follow me on twitter, buy me lunch, support me on patreon, and share this with your friends 😀
👋 Hi! I’m Kent C. Dodds. I work at PayPal as a full stack JavaScript engineer. I represent PayPal on the TC39. I’m actively involved in the open source community. I’m an instructor on egghead.io, Frontend Masters, and Workshop.me. I’m also a Google Developer Expert. I’m happily married and the father of four kids. I like my family, code, JavaScript, and React.