# JSX Made Simple: Learn the 3 Essential Rules

If you're writing React today, you're probably using JSX.

If you aren't familiar with JSX, it can be challenging to work with at first. For the most part, it should resemble HTML, but there are some subtle differences. Understanding these differences and the JSX ruleset will help you write better React code.

These are 3 rules you need to keep in mind.

## 1\. You must return a single root element

When you return JSX from a functional React component, it must be a single element.

This has to do with how JavaScript handles `return` statements. In JavaScript, you can't return more than one thing from a function.

Let's look at an example:

```typescript
// Wrong
function getName() {
    const firstName = 'John';
    const lastName = 'Doe';
    return firstName lastName;
}

// Correct
function getName() {
    const firstName = 'John';
    const lastName = 'Doe';
    return [firstName, lastName];
}
```

In this example, the function `getName` returns a `firstName` and a `lastName`. Since this is JavaScript, there's no way to return both values directly. To get around this, you can wrap both values *before* returning them.

One way to wrap the values is with an array.

**JSX works the same way.**

While JSX might look like HTML, it's a bit different. When you build your React code to be distributed to users, the JSX gets converted to function calls that return objects. You can read my blog post about how [React converts JSX to HTML](https://blog.thesshguy.com/react-jsx-to-html) to learn more.

Since the JSX ultimately gets converted into an object at runtime, it must abide by the same JavaScript rules:

```typescript
function MyComponent() {
    return <div id="my-id">My Component</div>;
}

// The code above gets converted to:
function MyComponent() {
    return React.createElement(
        'div',
        { id: 'my-id' },
        'My Component'
    );
}

// The code above can be replaced with the following
// (createElement returns an object)
function MyComponent() {
    return {
        'type': 'div',
        'key': null,
        'ref': null,
        'props': {
            'id': 'my-id',
            'children': 'My Component'
        },
        '_owner': null,
        '_store': {}
    };
}
```

So what do you do when you need to return multiple JSX elements?

### Multiple JSX elements can be wrapped with a Fragment

React provides a workaround with the [Fragment syntax](https://beta.reactjs.org/reference/react/Fragment). A Fragment is an empty JSX tag that can wrap other JSX elements. Fragments render their children *directly* without wrapping them in a separate HTML tag:

```typescript
function MyComponent() {
    return (
        <>
            <div>Child One</div>
            <div>Child Two</div>
        </>
    );
}
```

## 2\. All JSX tags must be closed

For most HTML elements, (e.g. `div`) this should feel natural.

However, some HTML tags don't have a closing tag. For those elements or for custom components that don't have children, things will feel a bit different. When you write the tag in JSX, you'll need to use a self-closing tag:

```typescript
function MyComponent() {
    return <img src="./myimg.png" alt="My Image" />;
}

function App() {
    return <MyComponent />;
}
```

**Note:** All JSX elements can be self-closing, including the `<div />` tag:

## 3\. Most JSX attributes and values use camelCase

Most attributes used with JSX elements resemble their counterparts that are used with HTML elements.

However, this doesn't always translate correctly since JSX is eventually converted into JavaScript objects. The JSX attributes become object properties. In JavaScript, it's a common pattern to read object properties into variables (e.g. [destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)):

```typescript
const { myProp } = { myProp: 10 };
console.log(myProp); // 10
```

These variables have limitations in terms of what they can be named. They can't be reserved keywords or have dashes. Because of this limitation, these attributes are typically named/renamed using camel-case.

Here are a few examples:

* The `font-weight` property in the `style` object becomes `fontWeight`
    
* The reserved keyword `class` becomes `className`
    
* `tabindex` becomes `tabIndex`
    

That last one should be fine either way, but I assume it's camel-cased to ensure consistency between the attributes.

You can get the [full list of these attributes here](https://beta.reactjs.org/reference/react-dom/components/common).
