Introduction to JSX

We learned about creating components in the previous article.

For the markup, you used JSX even if it looked like regular old markup.

JSX is a syntax extension for JavaScript that allows developers to write HTML-like code within their JavaScript code.

JSX is not a requirement for using React, but it's a common practice among developers because it simplifies the process of creating and managing UI components.

In a React application, JSX defines the structure and appearance of a component's output, making it easy to visualize the final rendered result.

In this article, we will dive into JSX so you can understand what it does and how it can help us.

Introduction to JSX

Benefits of Using JSX

Familiar syntax: JSX resembles HTML, making it easy for developers familiar with HTML and JavaScript to read and write JSX code. Improved readability: Combining markup and logic in a single file can make the code more readable and easier to maintain, especially for complex components. Enhanced productivity: JSX allows developers to create reusable components and compose them together, leading to a more efficient development process.

How JSX Works in React

In a React application, JSX is used within components to define the structure and appearance of the rendered output. When a component is rendered, the JSX code is transformed into JavaScript function calls that create and manipulate DOM elements. This transformation is done using a transpiler like Babel.

Here's an example of JSX in a React component:

function HelloWorld() {
  return (
    <div>
      <h1>Hello, World!</h1>
      <p>We are learning JSX</p>
    </div>
  );
}

export default HelloWorld;

The JSX code within the Greeting component is transformed into JavaScript function calls that create DOM elements:

function HelloWorld() {
  return React.createElement(
    'div',
    null,
    React.createElement('h1', null, 'Hello, World!'),
    React.createElement('p', null, 'We are learning JSX')
  );
}

export default HelloWorld;

In this example, the React.createElement function creates DOM elements for the div, h1, and p tags. The browser then executes the transformed JavaScript code to render the UI.

I'm sure we can agree that if we imagine composing an entire page with the React.createElement function, we would go insane.

Thankfully we can use JSX.

Styling in JSX

In our next sections, we will see a more practical use of styles, but here is a brief introduction.

When styling HTML, you are undoubtedly used to specifying classes with the class attribute. In JSX/React, we use the className attribute, which will behave identically to the class attribute.

<h1 className="title">Hello!</h1>

Then you can write your CSS rules in a separate file:

h1 {
    font-size: 22px;
}

We can also use inline styles using a style attribute and pass it to an object with the CSS values. The object should have keys in camelCase and values as strings. For example:

const textStyles = {
  fontSize: "16px",
  color: '##ff0000',
};

return <p style={textStyles}>This is a styled paragraph.</p>;

Embedding JavaScript Expressions in JSX

JSX allows developers to embed JavaScript expressions within the markup using curly braces {}. This enables the dynamic rendering of content based on variables or component states (we will learn about this later).

Here's an example of embedding a JavaScript expression within JSX:

const user = {
  name: "Niall Maher",
  id: 134
};
return (
  <div>
    <h1>Hello, {user.name}!</h1>
  </div>
);

In this example, the user.name value is embedded within the h1 tag to display a personalized greeting message. This can become dynamic, and we will leverage this much more later.

Since we now know we can render JavaScript in JSX, let's look at some practical common examples of why you would use this.

Conditionally render data

Let's assume we are fetching our user data from elsewhere and unsure if the user will have a name. Let's refer to people without names as guests:

// ✨ Magically get a user object which may not have a name
return (
  <div>
    <h1>Hello, {user.name ? user.name : "guest"}!</h1>
  </div>
);

Lists of data

Imagine we have a list of users and want to show all their names.

We can easily do this in JSX:

const users = [
  {
    username: "CosmicExplorer42",
    id: 1,
    //...
  },
  {
    username: "JavaJolt87",
    id: 2,
    //...
  },
  {
    username: "SunsetDreamer19",
    id: 3,
    //...
  },
];

return (
  <div>
    {users.map((user) => {
       return <div key={user.id}>{user.username}</div>;
    })}
  </div>
);

In this example, we map over the users and return an array of div elements containing the usernames. We also need to supply a unique key

This array of elements will be rendered as if we did the following:

// Output of the above code
return (
  <div>
    <div>CosmicExplorer42</div>
    <div>JavaJolt87</div>
    <div>SunsetDreamer19</div>      
  </div>
);

Notice how each element in our list was also given a unique key attribute.

For each item in a list, you should pass a string or a number that uniquely identifies that item among its siblings. React uses these keys to update items efficiently.

You'll see an error in the console if you forget, so don't worry. 😉

HTML vs JSX

After looking at some examples of JSX, let's talk explicitly about the differences between HTML and JSX. Since JSX is stricter than HTML, you will get errors and warnings if you don't follow these.

Always close tags: In JSX, all tags must be closed, including self-closing tags. For example, use <img src="example.jpg" alt="Example" /> instead of <img src="example.jpg" alt="Example">.

Use camelCase for attributes: JSX attributes follow the camelCase naming convention, meaning attribute names with multiple words should be written with the first letter of each subsequent word capitalized. For example, use onClick instead of onclick.

Use className instead of class: To assign CSS classes to JSX elements, use the className attribute instead of class. This is because class is a reserved keyword in JavaScript. For example, use <div className="container"> instead of <div class="container">.

Curly braces for JavaScript expressions: When embedding JavaScript expressions in JSX, use curly braces {}. For example, <h1>Hello, {name}!</h1>.

Comments within JSX: To write comments within JSX code, use the {/* */} syntax instead of the regular JavaScript comment syntax // or /* */. For example:

return (
  <div>
    {/* This is a JSX comment */}
    <h1>Hello, World!</h1>
  </div>
);

Parentheses for multi-line JSX: When writing multi-line JSX, wrap the entire expression in parentheses to prevent automatic semicolon insertion, which could lead to unexpected behavior. For example:

return (
  <div>
    <h1>Hello, World!</h1>
    <p>Welcome to JSX.</p>
  </div>
);

Only one root element: When returning elements, we can only return a single element with children. To make sense of what that means let's look at an example.

Here's an invalid return block:

// ❌ Trying to return two children instead of one
return (
    <h1>Hello, World!</h1>
    <p>Welcome to JSX.</p>
);

Now to fix it we can wrap the element:

// ✅ Valid 
return (
  <div>
    <h1>Hello, World!</h1>
    <p>Welcome to JSX.</p>
  </div>
);

We also even have a thing called Fragments which allows us to wrap our elements without a wrapper node.

// ✅ Valid with no <div> wrapper
// <>...</> is the syntax to use a Fragment
return (
  <>
    <h1>Hello, World!</h1>
    <p>Welcome to JSX.</p>
  </>
);

Homework

Use this online converter to convert some HTML into JSX and start seeing some of the nuanced differences.

What's next?

That was a lot! Take some time to practice what you have learned.

In the next section, we will start using state in React. "State" will allow us to update our screens and add interactivity.

You can find it here.


Follow me on Twitter or connect on LinkedIn.

🚨 Want to make friends and learn from peers? You can join our free web developer community here. 🎉

ReactjsJavaScriptFrontendTutorialLibrary
Avatar for Niall Maher

Written by Niall Maher

Founder of Codú - The web developer community! I've worked in nearly every corner of technology businesses: Lead Developer, Software Architect, Product Manager, CTO, and now happily a Founder.

Loading

Fetching comments

Hey! 👋

Got something to say?

or to leave a comment.