JSX is a syntax extension to JavaScript, based loosely on the now-defunct E4X standard and kind of looks like this:
<SomeComponent someProp={someValue}>
<h1 className="heading">Hello world</h1>
</SomeComponent>
In layman's terms, however, JSX is simply syntactic sugar for React.createElement(component, props, children)
.
That means, the code above is transpiled (or translated) into the following:
React.createElement(SomeComponent, { someProp: someValue },
React.createElement('h1', { className: 'heading' },
'Hello world',
);
);
Since the latter is neither very simple to read nor particularly user-friendly, Facebook came up with this XML-inspired syntax now known as JSX. You can play with this babel compiler example to see how this works with your own code.
Conditional rendering
If you've used React for any amount of time, you've probably run into situations where you want to render something if
a particular condition is met. JSX has this quirk that it doesn't render undefined
, false
, true
and
null
, and you can use that fact to render something only if your condition is met:
const ArticleCard = (props = (
<div>
{props.title && <h2>{props.title}</h2>}
{props.lead ? <p className="lead">{props.lead}</p> : null}
{props.body}
</div>
));
Note that I just showed you two different ways of doing the same thing - both with something called logical short
circuting (&&
) and ternaries (a ? b : c
). Both are valid and both work, but I tend to use the first approach
in my own projects.
Props default to true!
If you've specified a prop, but not given it a value, it defaults to true. That means the following two components are equal:
<Button large={true}>Click me</Button>
<Button large>Click me</Button>
I tend to use the former, just so that I don't have to remember this little detail of the JSX spec, but it's definitely nice to know about. It can potentially make your code look a lot cleaner as well!
Components must be capitalized
When you transpile your code, you'll notice that lower case component names are passed as strings to
React.createElement
, while capitalized component names are passed as a reference to the component name:
<hello /> // becomes React.createElement('hello');
<Hello /> // becomes React.createElement(Hello);
This might lead to some problems, especially if you have a component that receives the DOM element it's supposed to render as a prop.
const Heading = props => {
const { tagName, children } = props;
return <tagName>{children}</tagName>;
};
However, you can get around this limitation by renaming that constant to have a capitalized first letter:
const Heading = props => {
const { tagName: TagName, children } = props;
return <TagName>{children}</TagName>;
};
Those damn children
JSX handles the children
property a bit different than the rest, in that you can specify it inside the opening
and closing tags of your component. React, however, doesn't really care - it's just props to them.
This means you can send in some other JSX, a string literal or even an array or a function as children. You can also just specify children as a regular prop, making the following two statements equal:
<h1>My heading</h1>
<h1 children="My heading" />
The latter approach is probably not something you'll see a lot in the real world, but the fact that children really just is a regular property (and not something magic) is great. If you've been following this calendar over the last few days, then you probably remember the article on HOCs and render props , which uses this fact to send in a function that renders JSX instead of plain JSX.
JSX is yay!
There is tons more to learn about JSX, but as long as you remember the beginning of this article, you should be good:
JSX is just syntactic sugar for React.createElement
. Now go make something cool!