Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 3

JSX: UI with JavaScript Power

Recommended resources

Hello! Welcome back.

In our last lesson, you successfully set up a complete React development environment with Vite. You now have a running project with a lightning-fast development server, and you've seen how Hot Module Replacement (HMR) keeps your development flow smooth.

Today, we're diving into JSX, the syntax you saw inside the App.jsx file. This lesson is all about learning how to describe what your user interface should look like using a powerful syntax that blends HTML and JavaScript. By the end, you will be able to write JSX syntax to describe UI elements and embed JavaScript expressions to make your UI dynamic.

What is JSX?

At first glance, JSX looks like you're writing HTML directly in your JavaScript files.

// This is JSX
const element = <h1>Hello, world!</h1>;

While it looks like HTML, it's actually a JavaScript Syntax Extension created by the React team. It allows you to write declarative, HTML-like code that describes your UI right alongside the JavaScript logic that controls it. This co-location of markup and logic is a core principle of React, based on the idea that they are inherently coupled.

To get a better sense of what JSX is and why it was created, let's watch a short video that provides some excellent context.

JSX - React In Depth

This video from the 'React In Depth' series by Tech with Nader explains the origin and purpose of JSX, contrasting it with older web development paradigms.

Watch from 00:33 to 02:29. This segment introduces JSX as a combination of HTML and JavaScript and explains the motivation behind it.

What's Happening Under the Hood?

Your browser doesn't understand JSX directly. Before your code is executed, a tool called a transpiler (in our case, Vite uses one behind the scenes) converts your JSX into regular JavaScript. Specifically, it converts each JSX element into a React.createElement() function call.

This function call creates a JavaScript object that React uses to construct the actual DOM elements. Understanding this transformation is key to building a solid mental model of how React works.

The following video demonstrates this transpilation process using online tools. Watching this will make the "magic" of JSX feel much more concrete.

JSX - React In Depth

Here, Nader demonstrates how JSX code is transformed into React.createElement() function calls. This is a crucial concept for understanding what's really going on.

Watch from 21:58 to 28:00. Follow along as he writes simple JSX and observe the JavaScript output on the right. Notice how nested elements become nested function calls.

So, this JSX:

<div className="container">
  <h1>My App</h1>
</div>

...becomes this JavaScript:

React.createElement(
  "div", 
  { className: "container" }, 
  React.createElement("h1", null, "My App")
);

As you can see, writing JSX is far more intuitive and readable than writing nested createElement calls by hand!


The Rules of JSX

Because JSX is a blend of HTML and JavaScript, it has a few strict rules you need to follow that differ from standard HTML. The official React documentation provides the clearest explanation of these rules.

Writing Markup with JSX - The Rules of JSX

Please read the following section from the official React documentation. It clearly outlines the three fundamental rules you must follow when writing JSX.

Read the section titled 'The Rules of JSX'. Focus on the three main rules presented: returning a single root element, closing all tags, and using camelCase for attributes.

Let's summarize those three essential rules:

  1. Return a single root element: A component can only return one top-level element. If you have multiple elements, you must wrap them in a single parent, like a <div>, or use a Fragment (<>...</>) if you don't want to add an extra node to the DOM.

    // Correct: Wrapped in a Fragment
    return (
      <>
        <h1>Title</h1>
        <p>Paragraph</p>
      </>
    );
    
  2. Close all tags: In JSX, every tag must be closed. This includes self-closing tags like <img>, <br>, and <input>, which must end with a />.

    // HTML
    // <img src="profile.jpg">
    
    // JSX (Correct)
    <img src="profile.jpg" />
    
  3. Use camelCase for attributes: Since JSX is JavaScript, and attributes become keys on a JavaScript object, attributes that contain a hyphen in HTML (like font-size) are written in camelCase (fontSize). The most common example is the class attribute, which becomes className because class is a reserved keyword in JavaScript.

    // HTML
    // <div class="card">
    
    // JSX (Correct)
    <div className="card">
    
Test your understanding!

Open the src/App.jsx file in the project you created in the last lesson. Replace the entire return statement's content with the following invalid code snippet. Use the rules you just learned (and the error messages in your browser's console) to fix it.

// This is invalid JSX. Fix it!
export default function Bio() {
  return (
    <div class="intro">
      <h1>Welcome to my website!</h1>
    </div>
    <p class="summary">
      You can find my thoughts here.
      <br><br>
      <b>And <i>pictures</b></i> of scientists!
    </p>
  );
}
Show answer

Here is the corrected, valid JSX. You needed to:

  1. Wrap everything in a single root element (a Fragment <>...</> is used here).
  2. Change class to className.
  3. Self-close the <br> tags to become <br />.
  4. Correctly close the nested <b> and <i> tags.
// This is the corrected, valid JSX.
export default function Bio() {
  return (
    <>
      <div className="intro">
        <h1>Welcome to my website!</h1>
      </div>
      <p className="summary">
        You can find my thoughts here.
        <br />
        <br />
        <b>And <i>pictures</i></b> of scientists!
      </p>
    </>
  );
}

Embedding JavaScript Expressions with {}

The real power of JSX comes from its ability to seamlessly embed dynamic JavaScript values and expressions directly into your markup. You can do this by wrapping your JavaScript code in curly braces {}.

This lets you "open a window" from JSX back into the JavaScript world.

The following resource from the React docs covers this feature in detail.

JavaScript in JSX with Curly Braces

This article explains how to use curly braces to embed JavaScript variables, function calls, and even objects directly within your JSX.

Read the sections 'Using curly braces: A window into the JavaScript world' and 'Using “double curlies”: CSS and other objects in JSX'. Pay close attention to where you can use braces and the special syntax for inline styles.

Let's put this into practice in your App.jsx file.

Using Variables

You can reference any JavaScript variable directly inside JSX.

function App() {
  const name = "Alex";
  // The value of the 'name' variable will be rendered inside the h1 tag.
  return <h1>Hello, {name}!</h1>; 
}

Using Function Calls

You can also call functions. The return value of the function will be rendered.

function App() {
  const user = { firstName: 'Jane', lastName: 'Doe' };

  function formatName(user) {
    return user.firstName + ' ' + user.lastName;
  }

  // The formatted name will be rendered.
  return <h1>Hello, {formatName(user)}!</h1>;
}

Using JavaScript Objects for Inline Styles

A common use case for embedding objects is applying inline CSS styles. The style attribute in JSX accepts a JavaScript object, not a string. Since the object itself is wrapped in curly braces {}, and the JavaScript expression needs to be wrapped in curly braces {} within JSX, you end up with the "double curly" syntax: style={{...}}.

function App() {
  const customStyles = {
    color: 'blue',
    backgroundColor: 'lightyellow',
    padding: '10px',
    borderRadius: '5px'
  };

  // Note the camelCase CSS properties (backgroundColor, borderRadius)
  return <div style={customStyles}>This is a styled div.</div>;
}

A Fundamental Pattern: Rendering Lists with .map()

One of the most common tasks in UI development is rendering a list of items. Since you already know modern JavaScript, you'll be happy to know this is done using the standard array.map() method.

You can take an array of data, map over it, and return a JSX element for each item. This combines your JavaScript skills directly with JSX's declarative power.

The following video gives a clear, practical demonstration of this pattern.

React Tutorial for Beginners

This segment from Programming with Mosh's tutorial demonstrates exactly how to render a dynamic list of items using the .map() function in JSX.

Watch from 29:51 to 33:02. Pay special attention to why the key prop is necessary and how to assign it.

Here's the code pattern for rendering a list:

function App() {
  const items = ['Learn React', 'Build a Project', 'Deploy the App'];

  return (
    <ul>
      {items.map((item, index) => (
        // The 'key' prop is crucial for React's performance.
        // It helps React identify which items have changed, are added, or are removed.
        // We'll use the index here for simplicity, but a unique ID from your data is better.
        <li key={index}>{item}</li>
      ))}
    </ul>
  );
}

Go ahead and try this list-rendering example in your App.jsx!


Conclusion

Great work! You've just learned the fundamental syntax for building UIs in React. This is a huge step forward.

Let's recap the key takeaways from this lesson:

  • JSX is a JavaScript syntax extension that lets you write HTML-like markup in your JavaScript files.
  • It gets transpiled into React.createElement() function calls, which create objects that React uses to build the DOM.
  • You must follow three main rules: return a single root element, close all tags, and use camelCase for attributes like className.
  • You can embed any JavaScript expression (variables, function calls, etc.) directly into your markup by wrapping it in curly braces {}.
  • A common and powerful pattern is to use the array.map() method to transform data into a list of JSX elements.

In our next lesson, we will formalize our understanding of what a component is. You'll learn how to create your own functional components that return JSX, which is the building block for creating reusable and modular UIs.