JSX is not coming from React. Concretely, it is a syntax extension for JavaScript and looks like this following example:
const h1 = <h1>Hello, world!</h1>;
It also means that JSX is not valid JavaScript. Web browsers can’t read it!
If a JavaScript file contains JSX code, then that file will have to be compiled. That means that before the file reaches a web browser, a JSX compiler will translate any JSX into regular JavaScript.
JSX elements are treated as JavaScript expressions. They can go anywhere that JavaScript expressions can go.
It means that a JSX element can be saved in a variable, passed to a function, stored in an object or something else:
const myObject = {
h1: <h1>Hello, world!</h1>,
h2: <h2>My favorite hello world page</h2>,
h3: <h3 id="big">It is a good day to learn about JS!</h3>
}
The same rules as for HTML applies for JSX.
So, you can use HTML attributes as you can see on the h3 previous example.
But there are some exception!
Grammar in JSX is mostly the same as in HTML, but there are subtle differences to watch out for.
Probably the most frequent of these involves the word class.
Indeed we’ll need a specific keyword to use class in React
// HTML
<h1 class="big">Hello world</h1>
// The same JSX with React.js
<h1 className="big">Hello world</h1>
The reason is because JSX gets translated into JavaScript, and class is a reserved word in JavaScript.
In JSX, you have to include the slash on element. If you write a self-closing tag in JSX and forget the slash, you will raise an error.
// Ok in JSX
<br />
// NOT OK AT ALL in JSX
<br>
Nested JSX requires to use parentheses and can be saved as variables:
const helloWorldDivExample = (
<div>
<h1>Hello world</h1>
</div>
)
.map in JSXThe array method .map() comes up often in React.
It’s good to get in the habit of using it alongside JSX.
const names = ['Jon', 'Aria', 'Daeneris'];
const listNames = names.map(name => <li>{name}</li>);
<ul>{listNames}</ul>
In the above example, we start out with an array of names.
We call .map() on this array of names, and the .map() call returns a new array of <li>.
key attributeWhen you make a list in JSX, sometimes your list will need to use ids which is called keys:
<ul>
<li key="ex-01">Jon</li>
<li key="ex-02">Daeneris</li>
</ul>
keys are hidden on the DOM!
React uses them internally to keep track of lists.
Not all lists need to have keys. A list needs keys if either of the following are true:
No need you use them if it’s not answers to any previous conditions.
A JSX expression must have exactly one outermost element.
This is not a valid JSX:
const wrongExample = (
<p>Hello</p>
<p>World</p>
)
But this is valid:
const goodExample = (
<div>
<p>Hello</p>
<p>World</p>
</div>
)
Also, React allows to use a common pattern which called Fragment
render() {
return (
<React.Fragment>
<p>Hello</p>
<p>World</p>
</React.Fragment>
);
}
Standard way to render element with React is the ReactDOM library
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
<h1>Hello world</h1>,
document.getElementById('app')
);
React and ReactDOM both are specific React standard JavaScript libraries.
To render JavaScript on JSX, you have to use braces {}
ReactDOM.render(
<h1> {2 + 3} </h1>,
document.getElementById('app')
);
// => <h1> 5 </h1>
Same goes for variables
const text = 'world';
const jsxExpression = <p>Hello {text}!</p>
And for everything else such as function
function helloWorld() {
alert('Hello world!');
}
<img onClick={helloWorld} />
&&Like the ternary operator, && is not React-specific, but it is often used in React.
&& works best in conditionals that will sometimes do an action, but other times do nothing at all.
You can know more about conditional rendering on this article.
React.createElementYou must understand that you can write React code without using JSX at all!
The following JSX expression:
const h1 = <h1>Hello world</h1>;
can be rewritten without JSX, like this:
const h1 = React.createElement(
"h1",
null,
"Hello, world"
);
As a matter of fact, the compiler transforms the JSX element into React.createElement() for every JSX element.
To learn more about JSX, fell free to read the official Introduction.
Sometimes, we have to add some real JavaScript into JSX.
For example, we could add some style on a div such as:
<div style="color: darkred;">Hello world</div>
This works in pure HTML, but not in JSX.
Here’s what we need to do to make it work with JSX
import React from 'react';
import ReactDOM from 'react-dom';
const myDiv = <div style=>Hello World</div>;
ReactDOM.render(
myDiv,
document.getElementById('app')
);
Notice the double curly braces style=.
If you inject an object literal into JSX, and your entire injection is only that object literal, then you will end up with double curly braces.
Instead of using double curly braces, we can use variables and objects such as this example below
import React from 'react';
import ReactDOM from 'react-dom';
const styles = {
background: 'darkred',
color: 'whitesmoke',
marginTop: '100px'
}
// Replace that
const myDiv = <h1 style=>Hello World</h1>;
// Byt that
const myDiv = <h1 style={styles}>Hello World</h1>;
ReactDOM.render(
myDiv,
document.getElementById('app')
);
Notice that style attribute use camelCase instead of traditional hyphenated-lowercase. This is React stuff.
Also, there is no need to use quote when we need to specify px value.
{ marginTop: 30 }
// It the same as
{ marginTop: '30px' }
// But we need to specify another unity
{ marginTop: '2em' }