Reader small image

You're reading from  ReactJS by Example - Building Modern Web Applications with React

Product typeBook
Published inApr 2016
Reading LevelIntermediate
PublisherPackt
ISBN-139781785289644
Edition1st Edition
Languages
Right arrow
Author (1)
Vipul A M
Vipul A M
author image
Vipul A M

Vipul A M is Director at BigBinary. He is part of Rails Issues Team, and helps triaging issues. His spare time is spent exploring and contributing to many Open Source ruby projects, when not dabbling with React JS. Vipul loves Ruby's vibrant community and helps in building PuneRb, is the founder of and runs RubyIndia Community Newsletter and RubyIndia Podcast, and organizes Deccan Ruby Conference in Pune. He can be found @vipulnsward on twitter and on his site http://vipulnsward.com.
Read more about Vipul A M

Right arrow

Chapter 2. JSX in Depth

In the first chapter, we built our first component using React. We saw how using JSX makes the development easy. In this chapter, we will dive deep into JSX.

JavaScript XML (JSX) is an XML syntax that constructs the markup in React components. React works without JSX, but using JSX makes it easy to read and write the React components as well as structure them just like any other HTML element.

In this chapter, we will cover following points:

  • Why JSX?

  • Transforming JSX into JavaScript

  • Specifying HTML tags and React components

  • Multiple components

  • Different types of JSX tags

  • Using JavaScript expressions inside JSX

  • Namespaced components

  • Spread attributes

  • CSS styles and JSX

  • JSX Gotchas

At the end of the chapter, we will get familiar with the JSX syntax, how it should be used with React, and best practices of using it. We will also study some of the corner cases that one can run into while using JSX.

Why JSX?


Shawn had a great first day and he was just getting started with the next one at Adequate Consulting. With a mug of coffee, he startled Mike.

"Hey Mike, I saw that we used JSX for building our first component. Why should we use JSX when React has React.createElement?"

"You can use React without using JSX. But JSX makes it easy to build React components. It reduces the amount of code required to write. It looks like HTML markup. Its syntax is simple and concise and it's very easy to visualize the components that are getting built."

"Take an example of the render function of a component without using JSX."

// render without JSX
render: function(){
    return(React.createElement("div", 
                               null, 
                               "Hello React World!"));
}

"With JSX, it looks much better."

// render with JSX
render: function(){
    return <div>
      Hello React World
    </div>;
  }

"Compared to the previous non-JSX example, the JSX code is much more readable...

Transforming JSX into JavaScript


"Shawn, as I mentioned, the JSX is transformed to the native JavaScript syntax."

// Input (JSX):
var app = <App name="Mike" />;

"This will eventually get transformed to"

// Output (JS):
var app = React.createElement(App, {name:"Mike"});

Tip

Downloading the example code

You can download the example code files for this book from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

You can download the code files by following these steps:

  • Log in or register to our website using your e-mail address and password.

  • Hover the mouse pointer on the SUPPORT tab at the top.

  • Click on Code Downloads & Errata.

  • Enter the name of the book in the Search box.

  • Select the book for which you're looking to download the code files.

  • Choose from the drop-down menu where you purchased this book from.

  • Click on Code Download.

Once the file is downloaded, please...

HTML tags vs React components


"Mike, I am intrigued by one more thing. In JSX, we are mixing the React components as if they are simple HTML tags. We did this in our first component."

ReactDOM.render(<App headings = {['When', 'Who', 'Description']} 
                     data = {data} />, 
             document.getElementById('container'));

"The App tag is not a valid HTML tag here. But this still works."

"Yes. That's because we can specify both HTML tags and React components in JSX. There is a subtle difference though. HTML tags start with a lowercase letter and React components start with an uppercase letter." Mike explained.

// Specifying HTML tags
render: function(){
    return(<table className = 'table'>
           .....
           </table>);
}

// Specifying React components
var App = React.createClass({..});
ReactDOM.render(<App headings = {['When', 'Who', 'Description']}  
                     data = {data} />, 
                document.getElementById('container...

Self closing tag


"Another thing that you must have noticed is how the component tag is closed in ReactDOM.render" added Mike.

ReactDOM.render(<App .../>, document.getElementById('container'));

"As JSX is based on XML, it allows adding a self-closing tag. All the component tags must be closed either with self-closing format or with a closing tag."

"Thanks Mike! Things make much more sense now."

Multiple components


"Shawn, let's get back to our application. We are using almost the same code from last time but you can set up a new JSBin. We have included the latest React library and bootstrap library in the HTML tab. We have also added a container element, which we will render our React app."

<!DOCTYPE html>
<html>
  <head>
    <script src="https://code.jquery.com/jquery.min.js"></script>
    <link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" type="text/css" />
    <script src="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
    <script src="//fb.me/react-with-addons-0.14.3.js"></script>
    <script src="//fb.me/react-dom-0.14.3.js"></script>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>JSX in Detail</title>
  </head>
  <body...

JavaScript expressions


"Shawn, let's discuss a bit about how we have rendered the Rows and Headings tag."

render: function() {
    var headings = this.props.headings.map(function(name) {
      return(<Heading heading = {name}/>);
    });

   return <tr>{headings}</tr>;
  }

"We are rendering {headings}, which is a list of React components, directly by adding them in curly braces as children of the <tr> tag. These expressions that are used to specify the child components are called child expressions."

"There is another category of expressions called as JavaScript expressions. These are simple expressions used for passing props or evaluating some JavaScript code that can be used as an attribute value."

// Passing props as expressions
ReactDOM.render(<App headings = {['When', 'Who', 'Description']} 
                  data = {data} />, 
                document.getElementById('container'));

// Evaluating expressions
ReactDOM.render(<App headings = {['When', 'Who...

Namespaced components


"Shawn, you must have used modules and packages in languages such as Ruby and Java. The idea behind these concepts is to create a namespace hierarchy of code such that the code from one module or package doesn't interfere with another."

"Yes. Is something like this available with React?" Shawn asked.

"Yes. React allows creating components that are namespaced under a parent component so that they don't interfere with other components or global functions."

"We are using very generic names such as Rows and Headings that can be used later in other parts of the app too. So it makes sense to namespace them now, rather than later." explained Mike.

"Agreed. Let's do it right away," Shawn.

"We need to represent the top-level component as custom component rather than using the <table> element."

var RecentChangesTable = React.createClass({
  render: function() {
    return <table>
             {this.props.children}
           </table>;
  } 
});

"Now, we can replace...

Spread attributes


Shawn learned a lot of things about JSX but when he was reflecting on the previous steps, he came up with another question.

"Mike, as of now we are just passing two props to the App component: headings and changesets. However, tomorrow these props can increase to any number. Passing them one by one would be cumbersome. Especially, when we have to pass some data from the recent changes API directly. It will be hard to a keep track of the structure of the incoming data and pass it accordingly in the props. Is there a better way?"

"Another excellent question, Shawn. True, it might be cumbersome passing a large number of attributes to the component one by one. But we can solve this using the spread attributes."

var props = { headings: headings, changeSets: data, timestamps: timestamps };
ReactDOM.render(<App {...props } />, 
                     document.getElementById('container'));

"In this case, all the properties of object are passed as props to the App component. We...

Styles in JSX


"Mike, all of the things that we did today are very cool. When do we start adding styles? How can I make this page look pretty? Right now it's a bit dull." Shawn asked.

"Ah, right. Let's do that. React allows us to pass styles to the components the same way props can be passed. For example, we want our headings to be of the floral white color and maybe we want to change the font size. We will represent it in a typical CSS way as follows:"

background-color: 'FloralWhite',
font-size: '19px';

"We can represent this as a JavaScript object in the CamelCase fashion."

    var headingStyle = { backgroundColor: 'FloralWhite',
                         fontSize: '19px' 
                       };

Then, we can use it in each Heading component as a JavaScript object."

RecentChangesTable.Heading = React.createClass({
  render: function() {
    var headingStyle = { backgroundColor: 'FloralWhite',
                         fontSize: '19px' };
    return(<th style={headingStyle}>{this.props.heading...

JSX Gotchas


The day was heading to an end. Mike and Shawn were still discussing about this shiny new thing—JSX. Mike decided that it was time to tell Shawn about the issues with using JSX.

"Shawn, so how do you feel about using JSX?"

"I liked it so far. It's very similar to the HTML markup. I can pass attributes, styles, and even classes. I can also use all the DOM elements" explained Shawn.

"Yes. But JSX is not HTML. We have to always remember this. Otherwise, we will run into trouble."

"For example, if you want to pass some custom attribute that does not exist in the HTML specification, then React will simply ignore it."

// custom-attribute won't be rendered
<table custom-attribute = 'super_awesome_table'>
</table>

"It must be passed as a data attribute so that React will render it."

// data-custom-attribute will be rendered
<table data-custom-attribute = 'super_awesome_table'>
</table>

"We may also run into some issues while rendering the HTML content dynamically. In the...

Conditionals in JSX


"React embraces the idea of tying markup and logic that generates the markup together. This means that we can use the power of JavaScript for loops and conditionals."

"But if/else logic is a bit hard to express in markup. Therefore, in JSX, we can't use conditional statements such as if/else."

// Using if/else directly doesn't work
<div className={if(success) { 'green' } else { 'red' }}/>
Error: Parse Error: Line 1: Unexpected token if

"Instead, we can use a ternary operator for specifying the if/else logic."

// Using ternary operator
<div className={ success ? 'green' : 'red' }/>
React.createElement("div", {className:  success ? 'green' : 'red'})

"But ternary operator gets cumbersome with large expressions when we want to use the React component as a child. In this case, it's better to offload the logic to a block or maybe a function" Mike added.

// Moving if/else logic to a function
var showResult = function() {
  if(this.props.success === true)
    return <...

Non-DOM attributes


"Alright Shawn, it's time to take a detailed look at our application again. If you closely see the console output, you will see a few warnings related to Keys."

"Each child in an array should have a unique \"key\" prop. Check the render method of Rows. See http://fb.me/react-warning-keys for more information."

"In the render() method of Rows, we are rendering collection of the Row components."

RecentChangesTable.Rows = React.createClass({
  render: function() {
    var rows = this.props.changeSets.map(function(changeSet) {
      return(<Row changeSet = {changeSet}/>);
    });

    return <tbody>{rows}</tbody>;
  }
});

"During the rendering of list items, a component may move up or down in the DOM tree based on the user interaction. For example, in case of search or sorting, the items in the list can change their position. New items can also get added to the front of the list in case new data gets fetched. In such cases, React may remove and recreate components...

Summary


In this chapter, we dived deep into JSX. We discussed why using JSX makes development with React easy and how JSX gets transformed into the plain native JavaScript. We split big the single React component into small, focused components and understood the advantages of reusable, modular components. We saw different JSX tags, JavaScript expressions, and how React is taking advantages of ES6 features such as spread attributes. In the end, we discussed advanced topics such as namespaced components and some gotchas that we should keep in mind while using JSX.

In the next chapter, we will focus on data flow and models to access data and component life cycle and their use.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
ReactJS by Example - Building Modern Web Applications with React
Published in: Apr 2016Publisher: PacktISBN-13: 9781785289644
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at AU $19.99/month. Cancel anytime

Author (1)

author image
Vipul A M

Vipul A M is Director at BigBinary. He is part of Rails Issues Team, and helps triaging issues. His spare time is spent exploring and contributing to many Open Source ruby projects, when not dabbling with React JS. Vipul loves Ruby's vibrant community and helps in building PuneRb, is the founder of and runs RubyIndia Community Newsletter and RubyIndia Podcast, and organizes Deccan Ruby Conference in Pune. He can be found @vipulnsward on twitter and on his site http://vipulnsward.com.
Read more about Vipul A M