Tutorial to Using JSX and Rendering with React

Richard Rembert - Sep 6 '22 - - Dev Community

If you’re new to React, you’ll likely have heard about JSX, or JavaScript XML — it’s an XML-like code for elements and components. In this article, we’re going to take a look at what JSX is & why we should use it in our React applications. We’ll also take a look at what elements are, and how we can render them to the DOM.

What is JSX?

As mentioned, JSX is an XML-like code which we can use when coding with React. It was developed by the team at Facebook & is mean’t to provide a more concise syntax, helping to simplify the developer experience. Let’s take a look at our first example:

const greeting = <h1>Hello, World!</h1>;
Enter fullscreen mode Exit fullscreen mode

Simple, right?

What we have here is neither a string nor HTML. It’s JSX! We can use it to harness the full power of JavaScript when building our UI elements. While it’s not mandatory, it’s certainly an extremely useful tool — it does a great job of making it clear when we’re working with UI inside of our JavaScript code.

Using JSX

Let’s extend our above example to include an embedded expression:

const user = 'Richard Rembert';
const greeting = <h1>Hello, {user}</h1>;

ReactDOM.render(
  greeting,
  document.getElementById('root')
);
Enter fullscreen mode Exit fullscreen mode

We use curly braces {} to embed the variable into our JSX expression. And within those curly braces we could embed any valid JavaScript expression. Such as user.firstName or printName(user) for example.

Note: We’ll look at rendering in detail later in the article, don’t be to concerned about the above render method just yet!

Let’s embed the result of a called JavaScript function:

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

const user = {
  firstName: 'Richard',
  lastName: 'Rembert'
};

const greeting = (
  <h1>
    Hello, {printName(user)}!
  </h1>
);

ReactDOM.render(
  greeting,
  document.getElementById('root')
);
Enter fullscreen mode Exit fullscreen mode

JSX Under the Hood

So whats actually going on with JSX, when we render components?

function Greeting() {
  return <h1>Hello, World!</h1>
}
Enter fullscreen mode Exit fullscreen mode

Each element being rendered by the Greeting component are transpiled down into React.createElement calls. The above example transpiles to:

function Greeting() {
  return React.createElement("h1", {}, "Hello, World!")
}
Enter fullscreen mode Exit fullscreen mode

React.createElement()

Let’s see another example:

const greeting = (
  <h1 className="speak">
    Hello, world!
  </h1>
);
Enter fullscreen mode Exit fullscreen mode

When compiled, this code looks as follows:

const greeting = React.createElement(
  'h1',
  {className: 'speak'},
  'Hello, world!'
);
Enter fullscreen mode Exit fullscreen mode

Both of these code blocks are identical. And essentially an object is created like so:

const greeting= {
  type: 'h1',
  props: {
    className: 'speak',
    children: 'Hello, world!'
  }
};
Enter fullscreen mode Exit fullscreen mode

This object is known as a React element, and it functions a lot like a description of what you see on the screen. React uses these objects to build the DOM and keep it up to date.

Essentially, JSX is really just making the React.createElement(component, props, …children) function much more pleasing on the eye. Another example:

<Navbar backgroundColor = "purple" opacity = {0.8}>
  Menu bar
</Navbar>
Enter fullscreen mode Exit fullscreen mode

Will transpile to:

React.createElement(Navbar, {
  backgroundColor: "purple",
  opacity: 0.8
}, "Menu bar");
Enter fullscreen mode Exit fullscreen mode

Let’s now move on the see a few more concepts.

Props in JSX

We’ll take a deep dive into props in my next article! For now it's good to remember that when building components — they’ll often render children, which require data to render correctly. The parameters we pass in are what we call props. In JSX, there are a few ways we can do this, such as:

// Defaults to "true" if no value is passed
<MyComponent connected />
// String literals passed as props
<MyComponent user= "Bob Burger" />
// Expressions (below example will evaluate to 10)
<MyComponent total = {1 + 2 + 3 + 4} />
// Spread attributes: passes the whole props object
<MyComponent selected = {...this.state} />
Enter fullscreen mode Exit fullscreen mode

Note: if statements and for loops are not expressions in JavaScript, so they cannot be used in JSX directly! Instead, you could code it like so:

function NumberType(props) {
  let answer;
  if (props.number % 2 == 0) {
    answer = <strong>even</strong>;
  } else {
    answer = <i>odd</i>;
  }
  return <div>{props.number} is an {answer} number</div>;
}
Enter fullscreen mode Exit fullscreen mode

We can see our props passed into the conditional, evaluated and then returned — all via JSX.

Children in JSX

As your apps become larger, you’ll find some components will need to render children. And then those child components will also need to render further children, and so on! With JSX, we can manage these tree-like structures of elements quite well. The rule of thumb is — whatever elements a component returns become its children.

Lets take a quick look at the ways to render child elements with JSX:

String Literals

<MyComponent>I'm a child!</MyComponent>
Enter fullscreen mode Exit fullscreen mode

In this very basic example, the string I’m a child is a child of MyComponent and it's accessible via props.children of MyComponent.

JSX Elements as Children

Say we want to return an HTML child <header>, which has two of its own children: <Nav /> and <SearchBox />. We could do this like so:

function Header(props) {
  return (
    <header>
      <Nav />
      <SearchBox />
    </header>
  )
}
Enter fullscreen mode Exit fullscreen mode

Expressions

We can also pass expressions as children, to render to our UI. This would be very useful with a to-do list app, for example:

function TodoItem(props) {
  return <li>{props.content}</li>;
}

function TodoList() {
  const todos = ['vacuum', 'do laundry', 'get a new client'];
  return (
    <ul>
      {todos.map((content) => <TodoItem key={content} content={content} />)}
    </ul>
  );
}
Enter fullscreen mode Exit fullscreen mode

Functions

Functions can be useful when handling repetition, such as rendering repeated UI elements. We can create the structures that React will automatically render for us.

Let’s look at an example where we use a .map() function to create new pages on a website:

// Array of current pages
const pages = [
  {
    id: 1,
    text: "Home",
    link: "/"
  },
  {
    id: 2,
    text: "About",
    link: "/about"
  },
  {
    id: 3,
    text: "Contact",
    link: "/contact"
  }
];
// Renders a <ul> which generates the <li> children
function Nav() {
  return (
    <ul>
      {pages.map(page => {
        return (
          <li key={page.id}>
            <a href={page.link}>{page.text}</a>
          </li>
        );
      })}
    </ul>
  );
}
Enter fullscreen mode Exit fullscreen mode

To add a new page to our website, we just need to add a new object to the pages array & let React handle the rest.

Rendering Elements

As I’m sure you’ve seen throughout this article, when working with JSX we’re working with elements to render into our page. An element describes what you see on the screen:

const element = <h1>Hello!</h1>;
Enter fullscreen mode Exit fullscreen mode

Multiple elements such as this when combined, will form components. We’ll be taking a detailed look at components in my next article.

Rendering Our Elements to the DOM

Typically, we’ll have a <div> like so, in our HTML:

<div id="root"></div> 
Enter fullscreen mode Exit fullscreen mode

This is known as our DOM node. Everything inside of it is handled by React DOM.

And to render a React element into our root node, we pass both to ReactDOM.render(), like so:

const element = <h1>Hello!</h1>;
ReactDOM.render(element, document.getElementById('root'));
Enter fullscreen mode Exit fullscreen mode

Hello! will render to our page.

Updating Rendered Elements

Note that React elements are immutable! Once an element is created, you can’t change its children or its attributes. If if wish to update the UI, you’ll need to create a new element and pass it to ReactDOM.render().

Summary

There we go! We’ve covered the basics of JSX and rendering. I hope you’re beginning to see how useful these concepts are to us as developers, building React apps.

By harnessing the power of JSX to pass around elements in JavaScript, we’re building very workable code. The structure of JSX plays incredibly well with React, and despite the fact that JSX isn’t mandatory — it makes for a fantastic development experience.

Conclusion

If you liked this blog post, follow me on Twitter where I post daily about Tech related things!
Buy Me A Coffee If you enjoyed this article & would like to leave a tip — click here

🌎 Let's Connect

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .