One of the weirdest things to me when I started learning React was this JSX syntax. What is it? Where does it come from? And how can I make really cool stuff with this?
3 min read
·
By Kristofer Giltvedt Selbekk
·
December 10, 2017
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.
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.
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!
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>;
};
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.
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!
Loading…
Loading…
Loading…