Table of Contents
In this lesson, you will learn about JSX that allows us to easily write HTML code in React. JSX was introduced in the previous lesson. We will go into more detail regarding JSX in this lesson.
Introduction to JSX in React
Every web page requires some templating syntax to create the view or UI. We have many examples, such as PHP using blade templating engine, NodeJS using EJS, etc. They all allow the developer to create dynamically generated HTML pages.
Server-side rendering of HTML was popular back then, but these days, we do client-side rendering using modern frameworks and libraries like React, and JSX is the templating syntax used together with React.
Why do we need JSX?
JSX is not mandatory if you want to code your app in React. You can create the view and the UI without writing a single line of JSX. How is that possible…?
The secret is that React has an inbuilt method to create elements and components(UI building blocks in React). When the JSX syntax is compiled, it converts it to createElement()
calls behind the scenes. But it is often confusing and error-prone to create elements using this functional syntax. Therefore, we use JSX, which is more clean and readable.
React without JSX
const myElement = React.createElement('h1', {}, 'Hello React!'); ReactDOM.render(myElement, document.getElementById('root'));
React with JSX
const myElement= <h1>Hello React!</h1>; ReactDOM.render(myElement= , document.getElementById('root'));
The JSX Syntax
Since JSX is not a part of the core React Library, it has to be compiled through tools like Babel into React.createElement()
calls. Therefore, it is called JavaScript extension (JSX). Using “create-react-app” will install everything properly that you need to get started with JSX and React.
Basic Structure
If you have ever written HTML before, then you already know 80% of the JSX syntax. Just like the HTML tags, JSX uses XML like syntax to represent React elements. It can have attributes and children and it is very alike.
import React, { Component } from 'react' class SharePage extends Component { render() { return () { <div> { /* JSX code*/ } <h1> Share your post </h1> <p> Click the button below </p> <button> Share </button> </div> } } }
However, the interesting thing to note is that JSX does not require any quotes or escaping. You can directly write JSX in your javascript code!
But JSX does not create an HTML element. Instead, it creates a react element; the rest of the actual DOM management is handled by React. JSX is used for rendering both HTML-like elements(div, ul, li) and user-defined components.
Expressions
It is the power of templating in JSX. You can embed any expression inside the JSX syntax within curly braces {}
, such as a number, string, boolean, array, object, function, or variable. These are evaluated and interpolated by the JSX compiler.
import React, { Component } from 'react' class SharePage extends Component { render() { const { comment: { text, user, createdAt } } = this.props return ( <div className = "comment - display"> <UserDisplay user = { user } /> <p className = "date - display"> { new Date(createdAt).toDateString() } </p> <p className = "mt - 1 mt - b"> { text } </p> </div> ) } }
One common use of expression includes the interpolation of variables. The variables inside these expressions are evaluated dynamically. And the cool part is that whenever the state/prop changes in react, the JSX template is re-rendered to reflect the DOM changes.
<div className = {"myclassName" } > { 1 + 2 } {'hello' + 'world' } { /* comment in JSX */ } </div> // will output as <div>3 helloworld</div> in the DOM
Also, comments inside JSX are only possible inside expressions.
Props and attributes
Attributes in HTML are the additional information specified for an element. Similarly, JSX can also accept attributes to specify more information about the element.
We may also use expressions for the values of those attributes. Commonly, the term prop
is used in React and refers to the attributes passed to the JSX/React element.
One thing to note is that the attribute names become camelCased
in JSX. We need to be careful when naming some attributes that are fine in HTML but not in JSX:
1. class
becomes className
, because in javascript, class
is a keyword.
2. Events like click, submit are written as onClick
, onSubmit
, and so on.
3. The for
attribute in the label tag is written as htmlFor
in JSX.
Note how in the example below, className
and onClick
were used. It is optional to use expressions for className
values unless you want to use some javascript.
<button className = { 'btn engage-btn ${liked ? 'active' : ''}' } onClick = { this.handleClick } > <i className = "fas fa" /> { liked ? 'Liked' : 'Like' } {''} </button>
Nesting JSX
A JSX element can have text or other JSX elements between the opening and closing tags. However, JSX is more strict like XHTML. If a JSX element does not have any children, then it must be self closed by adding a slash before the closing angle bracket.
<div> /* Elements without children must be self closed as below */ <MyComponent /> <br /> </div>
Components with JSX
Components are reusable building blocks of UI in React and 90% of the time, React developers work with components. A component returns a JSX element that can contain many child elements.
Once we define a component using the Component class, we can now render or even nest them inside other components. We should remember that a component’s name must start with a capital letter.
In the example below, UserDisplay is a user-defined component, and user is the prop.
<div className = "bg - white p-2"> <UserDisplay user = { user } /> <p className = "post - date"> { new Date(createdAt).toDateString() } </p> </div>
Any attribute (prop) that we pass to the Component using JSX becomes accessible through the this.props.propName
property. If any children were defined, we can access it using this.props.children
.
Flexibility of JSX
The advantage of using JSX is that it is just like any other value in JavaScript. After all, it is just an object behind the scenes. So, JSX can be stored in a variable, returned from a function, and can be interpolated inside other JSX syntax.
render() { // store jsx code const JSX = < h1 > Jsx code < /h1> return ( <button className = "btn" onClick = { this.handleClick } > { /* comment in JSX */ } { /* reuse the JSX code using variables */ } { JSX } { JSX } Comment </button> ) }
This is very powerful. Most of the time, we need to dynamically generate JSX based on an array or object of some data. We can also group up repeating JSX code in a variable and reuse them. There are many possibilities, and you only get better with practice!
Common Use Patterns
When we create a component, we write the JSX code after the return statement of the render()
method. We highlight here two of the common techniques used with JSX:
1. Conditional Rendering
Sometimes it is necessary to display/hide a JSX element depending on some conditions. We cannot use if statements inside a JSX expression {}
, so we have to use the conditional operator testExpression ? expression1 : expression2
render() { const { name, link } = this.props return ( <Link to = { '/${link}' } className = "menu - item" > { /* conditional rendering */ } { link === 'home' ? <h1>Home< /h1> : name} </Link> ) }
If the testExpression link === ‘home’
is true, then the first part <h1>’Home’</h1>
before the colon :
runs, otherwise the second expression (name variable) after the colon :
runs.
2. Rendering elements from an array
Many times we have to create very similar elements where only the data differs. Say if you want to render an unordered list of fruits or vegetables in an array. They all need the same li elements but the fruit name will be different.
These are possible by using the .map()
method of javascript. Using map()
, we can process each of the array elements and convert them to JSX elements. The map method takes a callback with two parameters: the current array element and an optional index. The callback then returns the desired JSX syntax.
This example below shows a practical example of rendering multiple elements using the comments array. The map method returns multiple JSX elements or components.
export default class CommentContainer extends Component { render() { const { comments } = this.props return ( <div className = "comment - container"> <h5 className = "mb-3"> Comments </h5> { comments.map(comment => ( <Comment comment = { comment } /> )) } </div> ) } }
Points to remember
JSX is just one of the pieces from the wonderful world of React. But it still goes hand in hand with React and is quite important. Becoming comfortable with it is not hard. It’s elegant, easy, and effective!