#3 A tour of JSX - Delightful React

#3 A tour of JSX - Delightful React

what can you do JSX.png

The JSX syntax makes it very easy to create elements and components. Let us try to understand what all JSX can do so that we can prepare ourselves for the project that we'll be building in this book.

This chapter is more like a cookbook of recipes, where I will walk you through all the things that are possible with the JSX syntax.

JSX Syntax

The JSX (stands for Javascript XML) syntax is a more concise way of creating React components. It looks quite a bit like HTML which gives most frontend developers a familiar feeling while working with React. JSX is simple and powerful at the same time and understanding it is important before we create more powerful components.

bqc1gncxdhau0zfuxqmp.png

First of all, let's try creating a few more elements in the MyComponent component like so. All elements that the browser supports in HTML can be created using React.

function MyComponent(){
  return <div>
    <h1>Delightful React </h1>
    <img src="http://assets.delightful-react.com/scenery.jpg"/>
    <p>The best way to learn React! </p>
    <a href="https://google.com">Google </a>
    <br/>
    <button>Click Me! </button>
   </div>
}

1. Rendering strings

An important thing to note here is that whatever we put between the open and closing tags in a React element is rendered as-is. So in our h1 element we put in "Delightful React" and that is rendered as is (As a string). It is the same for all elements.

function MyComponent(){
  return <div>
    <h1>Delightful React </h1>
    ...
   </div>
}

2. Rendering variables

However, React is also capable of rendering dynamic values like variables. A variable/expression that needs to be evaluated needs to be put within a pair of braces and React will evaluate it’s value before rendering it.

function MyComponent(){
  const headingText = "Delightful React";
  return <h1>{headingText} </h1>
}

We can also render variables and strings together

function MyComponent(){
  const headingText = "Delightful React";
  return <h1>Heading is {headingText} </h1>
}

So the main takeaway here is that whenever React encounters a pair of curly braces, it evaluates the expression inside.

3. Conditional statements

We can also use operators like the ternary operator to run conditional statements.

function MyHeading(){
  const username = "bhargav"
  return <h1>{loggedIn ? username : "Please log in"} </h1>
}

Using the ternary operator, we can use our MyHeading component to render different content based on a condition. You can also use a more verbose syntax like here and use an if-else condition and return different JSX expressions based on a condition.

function MyHeading(){
  const headingText = "Delightful React";
  if(somethingIsTrue){
   return <h1>{headingText}</h1>
  }else{
   return <h1> Hello </h1>
  }
}

4. A React Component should always return

A React component should be returning a value at all times. It can't return undefined or have no return value.

This component below doesn't return anything and hence implicitly returns undefined.

function AnotherComponent(){

}

<AnotherComponent/>

This causes React to throw an error that looks like this.

Screenshot 2021-01-16 at 1.20.59 PM.png

Just as the error message mentions, if we want our component not to render any JSX in some conditions, we can return null.

function AnotherComponent(){
  return null
}

<AnotherComponent/>

A React Component must always return a value. If we don’t want the component to not render anything, we can return “null” from the component.

Rendering objects is not allowed

Finally, when we are using objects in JavaScript, it is important to know that objects can have different keys and values. So when an object is put inside curly braces, React does not know how to render it.

function MyHeading(){
  const user = {name: "bhargav"}
 //rendering an object is not allowed
 return <h1>{user}</h1>
}

This is why, rendering objects is not allowed in JSX expressions in JavaScript. Strings, numbers and boolean values are allowed, but not objects.

You can render it's properties though

function MyHeading(){
  const user = {name: "bhargav"}
 //rendering an object is not allowed
 return <h1>{user.name}</h1>
}

Composing components together

React components are composable and the JSX syntax supplements this in the best way.

comp.png

We already talked about composition in the first chapter about how JSX allows us to build components in such a way that they can be composed together, freely and in any level deep.

function Navbar(){/** ... */}
function Heading(){/** ... */}

function Content(){
  return <div>
    <Heading/>
     <p>Hello</p>
    <img/>
   </div>
}

function Page(){
  return <div>
    <Navbar/> 
    <Content/>
  </div>  
}

The plain JS way of using React.createElement is great but composing elements and components is not that straightforward/readable. JSX on the other hand makes composition look very easy. Hence, I thought I should reiterate it here in this chapter, that composition is easy in React thanks to JSX.

Composition is a very powerful feature, and as a React developer, this will be our bread and butter going forward.

As a closing thought, let's talk about how components look like.

Calling vs Rendering a component

Components are simply functions that return other elements or components, don't they? Then why do we need the component to be called with opening and closing tags when it can be used with parentheses? What is the difference?

Calling_vs_Rendering_a_function_component_Copy.png

  • We know that the component MyHeading can be rendered like this
function MyHeading(){
  return <h1>Hello </h1>
}

function MyComponent(){
   return <div>
    <MyHeading/>
  </div>
}
  • The same component can also be invoked as a function using a pair of parenthesis and it's return value can be evaluated inside a pair of parentheses.

function MyHeading(){
  return <h1>Hello </h1>
}

function MyComponent(){
   return <div>
    {MyHeading()}
  </div>
}
  • Well, at this point, both are identical and give the same result
  • There are slight differences in how React manages both scenarios internally. Still, they both produce the same end result where the internal elements of the component are rendered exactly the same way.

So, the point to note here is that, while these two methods of using a component are valid at this point, this will change after we start using Hooks. For now both of these approaches are interchangeable.

Great going so far!

We talked about JSX and it's syntax in more detail in this chapter because that will set up for future chapters and will help us build components faster. Let's talk about an awesome framework in the next chapter and take it to the Next level. Stay tuned.