# React Fundamentals: Understanding JSX

## Hello World 👋

Welcome to the 4th article of the series [My Review of Kent C. Dodds's EpicReact.Dev](https://hashnode.com/series/my-review-of-kent-c-doddss-epicreactdev-ckfv4gidh08efu9s1408v8tgp). Please note that this blog post series is just my review of the [EpicReact.Dev](https://epicreact.dev) workshop material. I am just trying to explain what I learned and understood in my own way. This is not in any way officially associated with [Kent C. Dodds](https://epicreact.dev) or [EpicReact.Dev](https://epicreact.dev). You would learn a lot more when you actually go through the `EpicReact.Dev` video explanations and workshop material yourself. The workshop material is also self-paced and open source. So, if you want to do the workshop yourself, you can go to [React Fundamentals Workshop Repo](https://github.com/kentcdodds/react-fundamentals) and follow the instructions there.

If you haven't read the previous articles in this series, please go and read them first before you continue. I will add links to the articles below.
1. [Introduction](https://blog.bhanuteja.dev/epic-react-introduction)
1. [Javascript You Need To Know For React](https://blog.bhanuteja.dev/epic-react-javascript-you-need-to-know-for-react)
1. [React Fundamentals - Intro to React Raw APIs](https://blog.bhanuteja.dev/epic-react-react-fundamentals-part-1)

In the previous article, you have learnt about React Raw APIs specifically `React.createElement()` and `ReactDOM.render()`. In this article, you will learn all about JSX.

### Table of Contents
- [Using JSX](#using-jsx)
    - [Writing Markup With JSX](#writing-markup-with-jsx)
    - [Adding Props To JSX](#adding-props-to-jsx)
    - [Interpolation In JSX](#interpolation-in-jsx)
    - [Spreading Props](#spreading-props)

### Using JSX

#### Writing Markup With JSX

JSX is the HTML-like syntactic sugar that finally gets compiled into couple of `React.createElement()` function calls.

Let's see a `Hello World` example of how JSX looks like.

```js
// JSX
const element = <div>Hello World</div>

// Above JSX compiles into following
const element = React.createElement("div", null, "Hello World")
```
Since JSX is not a valid javascript code, you have to add a compiler that compiles this code and converts it into a normal javascript code(in this case `React.createElement()` calls).

We can use [Babel](https://babeljs.io/) for this purpose. Babel converts our JSX code into javascript code in the browser itself. 

**Note:**
- In actual production-level applications, we would not be following this method of using babel that we see here. We will see more about this in future articles.
- While adding JSX code, Babel needs a way to find out which part of the code it needs to compile into JS. You also need to have a way to tell the browser to not evaluate any JSX code since if it does, it throws errors because JSX code is not a valid JS code. So, you need to wrap the JSX code between `<script type="text/babel">` and `</script>`. Any code between the script tag with type `text/babel` will be compiled by Babel and not evaluated by the browser.
- You can also play around with [Babel REPL](https://babeljs.io/repl#?builtIns=App&code_lz=MYewdgzgLgBArgSxgXhgHgCYIG4D40QAOAhmLgBICmANtSGgPRGm7rNkDqIATtRo-3wMseAFBA&presets=react&prettier=true) to see exactly how JSX is compiled to javascript.


You can add Babel to your application through CDN.
```html
<script src="https://unpkg.com/@babel/standalone@7.9.3/babel.js"></script>
```
In the previous article, we tried to create nesting elements markup using `React.createElement`.

```js
// This is the code that we used to create that markup.
const helloElement = React.createElement("span", {children: "Hello"})
const worldElement = React.createElement("span", {children: "World"})
const helloWorldElement = React.createElement("div", {
    children: [helloElement, worldElement]
})

// Let's try to create the same helloWorldElement using JSX
const helloWorldElement = <div><span>Hello</span><span>World</span></div>

// You can even split the JSX into multiple lines for more readability.
// It is recommended to add parenthesis around JSX when splitting them into multiple lines
const helloWorldElement = (
    <div>
        <span>Hello</span>
        <span>World</span>
    </div>
)
```
From the above example, we can see that JSX is more intuitive to work with than directly using `React.createElement`.

#### Adding Props to JSX
consider the below element created using `React.createElement` API

```js
const element = React.createElement("div", {className: "container"}, "Hello World")
```

Let's try to convert this to JSX code. Here you have a prop called `className`. The way to add the React props in JSX is to add them as attributes.

```js
const element = <div className="container">Hello World</div>
``` 

Let's see an example with multiple props.
```js
// js
const element = React.createElement("div", {className: "container", id: "hello"}, "Hello World")

// jsx
const element = <div className="container" id="hello"></div>
```

**Note:**
- Notice that in JSX we write `className` instead of `class` like in HTML. It's because in the corresponding `React.createElement` API, the name of the prop for class is `className`. We are directly adding props in `React.createElement()` to JSX as attributes. 

#### Interpolation in JSX
Let's see the English meaning of interpolation first. A quick google search gave me `The insertion of something of a different nature into something else`.

You already saw interpolation in one of the javascript concepts that we know - Template Literals. In template literals, we are inserting javascript expressions inside strings.

Interpolation in JSX is inserting javascript expressions into JSX. Let's see a basic example to know what I mean.

```js
// Without Interpolation
const element = <div className="container">Hello World</div>

// With JSX Interpolation
const nameOfClass = "container"
const content = "Hello World"
const element = <div className={nameOfClass}>{content}</div>
```
You can see in the example above we are interpolating `nameOfClass` and `content` into JSX. The way you do that is by wrapping them around inside curly braces.

Let's also look at how Babel compiles this down to.
```js
const element = React.createElement("div", {className: nameOfClass}, content)
```
So, basically, whatever you write inside those curly braces, the babel directly assigns them to the corresponding prop without changing anything.

You are not just limited to interpolating strings, you can interpolate any type of javascript expression into JSX. Let's see some examples
```js
const element = <div>{count + 1} Blogs</div>

const element = <div id={`blog-${blogId}`}>This is a blog post with id {blogId}.</div>

const element = (
    <div className={isMobile ? "mobile" : "desktop"}>
        This is {isMobile ? "Mobile" : "Desktop"} view
    </div>
)

const element = (
    <div>{isDesktop && (<span>Hello</span>)} World</div>
)
```
**Notes:**
- Ternary operator is also an expression, hence we are able to interpolate that in JSX
- Conditional AND and Conditional OR operators are also expressions and can be interpolated in JSX.
- Statements cannot be interpolated in JSX.

Let's see why statements cannot be interpolated in JSX.

Consider the following JSX where we interpolated an if statement
```js
const element = <div className={if(condition) func() }>Hello</div>

// let's try to convert this to React.createElement()
const element = React.createElement("div", {className: if(condition) func()}, "Hello")
// The above statement is not a valid javascript, a statement cannot be assigned to a variable.
// This is the reason why we cannot add statements inside interpolation.
```

#### Spreading Props
Consider the below example.

```js
const props = {
    id: "hello",
    className: "container",
    children: "Hello World"
}
const element = React.createElement("div", props)
// This will render <div id="hello" className="container">Hello World</div>

// Let's slightly change how we write props.
// This will produce the same exact result as above
const element = React.createElement("div", {...props})

// Let's try to convert this to JSX
// Note that in JSX, we can use all the tags as self-closing tags.
const element = <div {...props} />
```

From the above example, we can see that the way to spread the props in JSX is to use `{...props}`.

**Notes:**
- In JSX, the attributes are camelCased. For example, the equivalent of HTML attribute `aria-label` in JSX is `ariaLabel` and equivalent of `onchange` is `onChange`. I will add a couple of links at the bottom to learn more about these changes.
- In JSX, if you add an attribute, but do not assign any value to it, JSX treats it as a boolean attribute and assigns value `true` to it.
    ```js
    // Both of these are same
    const element = <button disabled={true}>Button</button>
    const element = <button disabled>Button</button>
    ```
- When assigning props, the order is important. The attributes to the right will override the same attributes that are to the left.
    ```js
    const element = <div className="default" className="primary">Hello World</div>
    
    // when the above JSX is rendered, it will be converted to following HTML markup.
    <div class="primary">Hello World</div>
    // The className attribute that is to the right will replace the className attribute that is to the left
    ```

### What's Next
In this article, you learned about JSX, adding props to JSX, interpolation in JSX, spreading props in JSX, etc. In the next article, we will see how to create custom components. We will also see how to style the elements in React.

#### Until Next Time 👋

---

You might also like the following articles that I wrote:
- [Introduction to React Raw APIs](https://blog.bhanuteja.dev/epic-react-react-fundamentals-part-1)
- [How I Gave A Modern Look For HackerNews Feed](https://blog.bhanuteja.dev/how-i-gave-a-modern-look-for-hackernews-feed)
- [Javascript You Need To Know For React](https://blog.bhanuteja.dev/epic-react-javascript-you-need-to-know-for-react)
- [My Review of Kent C. Dodds's EpicReact.Dev: Introduction](https://blog.bhanuteja.dev/epic-react-introduction)
- [React Fundamentals](https://blog.bhanuteja.dev/react-fundamentals)
- [Create Your Own Super Simple URL Shortener](https://blog.bhanuteja.dev/create-your-own-super-simple-url-shortener)
- [Why you should start using HSL color format](https://blog.bhanuteja.dev/why-you-should-start-using-hsl-color-format)
- [Embed Youtube Videos into Your Markdown Editor](https://blog.bhanuteja.dev/embed-youtube-videos-into-your-markdown-editor)
- [Babel Plugin To Remove Console Logs In Production](https://blog.bhanuteja.dev/babel-plugin-to-remove-console-logs-in-production)
- [Create Custom Markdown Parser](https://blog.bhanuteja.dev/create-custom-markdown-parser)
- [Add Typescript to your Next.js project](https://blog.bhanuteja.dev/add-typescript-to-your-nextjs-project)


---

If this was helpful to you, Please **Like** and **Share** so that it reaches others as well. To get email notifications on my latest articles, please subscribe to my blog by hitting the **Subscribe** button at the top of the page. You can also follow me on twitter [@pbteja1998](https://twitter.com/pbteja1998).

**Links and References:**
- [EpicReact.Dev](https://epicreact.dev) - Series of workshops with video explanations by [Kent C. Dodds](https://kentcdodds.com) based on which this blog post series is being written.
- [React Fundamentals Workshop Repo](https://github.com/kentcdodds/react-fundamentals) - Github Repo if you want to do the self-paced workshop yourself.
- [React Fundamentals Workshop Demo](http://react-fundamentals.netlify.app) - Production application of the above workshop repo.
- [Introducing JSX](https://reactjs.org/docs/introducing-jsx.html) - Official React Docs
- [DOM Elements And Their Attributes](https://reactjs.org/docs/dom-elements.html) - Official React Docs

%%[newsletter]
