Let’s talk about the JSX as opposed to HTML. We’ll brush over the basics of JSX, overview the main differences between JSX and HTML, and finish with some frequently asked questions about particular issues often encountered when writing JSX.
What is HTML?
HTML is a Hypertext Markup Language, the standard markup language for documents designed to displayed and viewed on the web in a web browser.
What is JSX?
JSX (JavaScript + XML) is an extension of JavaScript that allows you to write HTML directly within JavaScript, which has a few benefits of making your code more readable and exercising the full power of JavaScript within HTML.
JSX is not intended to implemented by browsers, it also doesn’t signify a proposal to incorporate JSX into the ECMAScript spec. JSX’s main intention is to be used by transpilers or preprocessors to transform these tokens into standard ECMAScript.
JSX is in many ways similar to HTML, however, it does come with certain conspicuous differences which we’ll cover in the next section.
Since JSX is not a valid JS code, it needs to be compiled into JS with a tool like Babel or similar.
A simple example of JSX:
const JSX = <h1>Hello world!</h1>;
or
const element = <h1>Hello world!</h1>;
Another example of JSX which looks like plain HTML but, in fact, is JavaScript:
<div id="foo">Hello world</div>
translates to:
someFunc("div", {id: "foo"}, "Hello world");
Since JSX is a syntactic extension of JS, you can write JS directly within JSX. To do so, you’ll need to brace your code within the curly braces for it to be treated as JS:
{ 'insert your JavaScript code here' }
To specify string literals as attributes, use quotes:
const element = <div tabIndex="0"></div>;
You should either use quotes (for string values) or curly braces (for expressions), but not both in the same attribute.
A few more examples of using expressions in JSX.
Example 1:
const name = 'John Doe'; const element = <h1>Hello, {name}</h1>; ReactDOM.render( element, document.getElementById('root') );
Or example 2:
const myelement = <h1>React is {10*10} times better with JSX</h1>;
Babel compiles JSX to React.createElement()
calls.
For example:
const element = ( <h1 className="greeting"> Hello, world! </h1> );
same as
const element = React.createElement( 'h1', {className: 'greeting'}, 'Hello, world!' );
and then this:
const element = { type: 'h1', props: { className: 'greeting', children: 'Hello, world!' } };
All these objects are called “React elements” and represent descriptions of what you want to see on the screen.
Fundamentally speaking then, JSX provides syntactic sugar for the React.createElement(component, props, ...children)
function.
For example,
<div className="sidebar" />
Compiles to:
React.createElement( 'div', {className: 'sidebar'}, null )
JSX vs HTML: overview
The first and one of the most important differences of JSX as opposed to HTML is that nested JSX must return a single element, which we’ll call a parent element that wraps all other levels of nested elements:
<div> <p>veggie</p> <p>fruit</p> <p>fish</p> </div>
Without the wrapper element, JSX will not transpile.
In React, we can render JSX directly into HTML DOM using React rendering API, aka ReactDOM. The formula for rendering React elements looks like this:
ReactDOM.render(componentToRender, targetNode)
ReactDOM.render()
must be called after the JSX elements declarations.
Another important difference is that in JSX you can’t use the world class
to define HTLM classes, since class
is a reserved word in JavaScript, instead, use — className
.
Moreover, all HTML attributes and event references in JSX become camelCase, this way, onclick
event becomes onClick
and onchange
— onChange
.
Another important difference between JSX and HTML is the closing tag. In HTML almost all tags have an opening and a closing tag except probably a few like
<br />
…in JSX, however, any element can be written as a self-closing tag, for example:
<div />
Example:
const element = <img src={user.avatarUrl} />;
Since the JSX component represents HTML, you can put several components together to create a more complex HTML page.
The fact that JSX looks like HTML doesn’t make it any more of HTML, in fact, you can still write normal functions bypassing the HTML-like syntax.
The bottom line is that JSX is not HTML or a template engine. Let’s briefly outline the differences between those template engines and JSX in the next section.
JSX and templates
With template engines, such as those used in Angular and Vue, you feed the library a string, which is then converted into JavaScript which, in turn, generates virtual DOM structures when executed. In templates, importing helper functions or call methods is only possible through directives, which are the bridge between the HTML and JS.
Here’s how it works:
JSX/JS: javascript -> vdom
Template: string -> javascript -> vdom or string ->JSX/JS
Compare 2 syntaxes below.
JSX
<Page index="1"> <h1>About me</h1> <AboutMe content={aboutMeContent} /> </Page>
HTML templating:
<div class="page"> <h1>{{aboutMeTitle}}</h1> <div>{{aboutMeContent}}</div> </div>
While both examples convert to plain JavaScript, JSX is still a preferable option if compared with HTML templating, since the former allows taking advantage of the expressiveness of JavaScript at any point in the code.
FAQ:
Is JSX HTML?
No, JSX is JavaScript XML, an extension of JavaScript that allows writing HTML in React. HTML is a standard markup language for documents designed for the web browser.
How to convert HTML to JSX? // How to convert HTML formatted string to JSX?
There are a bunch of solutions to convert HTML to JSX/React, some of which are:
- Using an HTML to JSX compiler, like https://magic.reactjs.net/htmltojsx.htm {same: https://github.com/reactjs/react-magic/blob/master/README-htmltojsx.md} or http://www.htmltoreact.com/ or https://transform.tools/html-to-jsx
- Converting HTML pages into React components https://github.com/roman01la/html-to-react-components
- Using a library to convert raw HTML to a React DOM structure https://www.npmjs.com/package/html-to-react
- Visual Studio Plugin https://marketplace.visualstudio.com/items?itemName=riazxrazor.html-to-jsx
How to define an HTML class in JSX in React?
Since class
is a reserved name in JavaScript, use className
instead.
const JSX = ( <div className=”myDiv”> <h1>Add a class to this div</h1> </div> );
How to append HTML to the JSX variable? // How to put HTML as a string value JSX?
Using dangerouslySetInnerHTML
:
dangerouslySetInnerHTML
is React’s replacement for using innerHTML
in the browser DOM. In general, setting HTML from code is risky because it’s easy to inadvertently expose your users to a cross-site scripting (XSS) attack. So, you can set HTML directly from React, but you have to type out dangerouslySetInnerHTML
and pass an object with a __html
key, to remind yourself that it’s dangerous.
function MyComponent() { const htmlToPaste = '<p class="some-class">do not try this in production</p>'; return ( <div className="MyComponent"> <h1>Title</h1> <div dangerouslySetInnerHTML={{__html: htmlToPaste}} /> </div> ); }
How to run an external JSX?
To run the script with JSX need just configure @babel/plugin-transform-react-jsx
Input
const profile = ( <div> <img src="avatar.png" className="profile" /> <h3>{[user.firstName, user.lastName].join(' ')}</h3> </div> );
Output
const profile = React.createElement("div", null, React.createElement("img", { src: "avatar.png", className: "profile" }), React.createElement("h3", null, [user.firstName, user.lastName].join(" ")) );
How to comment out in JSX?
To comment out something inside JSX, use the syntax {/* */}
to wrap around the text that you’d like to comment out.
For example,
const JSX = ( <div> {/* this is a comment */} <h1>Headline 1: Block of JSX</h1> <p>Here's a paragraph</p> </div> );
JSX element not appearing in HTML console {inspector}: what to do?
React uses a Virtual DOM to optimize the rendering process while using the developer tools by default you can inspect a standard DOM only.
For example, React Developer Tools extension can be used for that.
How to add bootstrap HTML to JSX?
You can’t just copy bootstrap templates into React, in order to do so, you’ll first need to convert bootstrap HTML into JSX (please, see above for the available converters) and then copy that code into React
How to style HTML? vs How to style JSX?
1. External CSS files
The main way to use styles for an HTML page is to attach a separate file (using CSS-preprocessors or not) The same approach can be applied to JSX with the only difference that instead of class
attribute in JSX used className
.
HTML
<div class="pretty">content</div>
JSX
<div className="pretty">content</div>
2. Inline CSS
Using the style attribute is not the most convenient solution for HTML, but it works for JSX. In this case, styles can be flexibly controlled, including the component level.
HTML
<div style="border-color: blue;">content</div>
JSX
const divStyle = { borderColor: 'blue', } return <div style={divStyle}>content</div>
Given that the JSX is a syntax extension to programming language there are several additional approaches for creating and controling styles: CSS in JS, Styled Components and CSS Modules.
Further reading on the blog:
Building React Components Using Children Props and Context API
React Hooks and RxJS
React vs Angular