Codementor Events

Understanding JSX

Published Jul 26, 2018Last updated Jan 22, 2019

In my beginning (React) days, after going through a few examples, I put jsx to use and got the job done. But it took some time to master the concept. And in the process there are some ‘aha’ moments, which I am going to share now.

Loop

One of the most common and frequent use case is, to loop through an array of data and render them.

<ol>
{
  data.map(item => <data key={item.id}> {item.label}</data>)
}
</ol>

This looks quite simple. I wanted to achieve the same result using the for statement. I tried the below and failed.

<ol>
{
  for(let i = 0; i < data.length; i++) {
    <data key={item.id}> {item.label}</data>
  }
</ol>

I was wondering why it is not working, even through it looks very intuitive.

I reread the documentation of JSX to get a better understanding.

JSX is not a technology on its own. It is just ‘syntactic sugar’ where function calls are represented as tags for the ease of reading and writing. Thats it.

<div className="info">Hello and Welcome</div>

The below function is the equivalent of the above jsx.

React.createElement(
  'div',
  {className: 'info'},
  'Hello and Welcome'
)

So each jsx node is nothing but a function, and

  1. the first argument is the html tag type,
  2. the second argument is an object consisting of attributes
  3. and the third argument is the children of the node. Here we have a simple text as children. But you can imagine more nested and complex children.

The children of jsx can only be expressions and it cannot be statements.

This is the reason why we cannot have for-loop as children. Expression evaluates to value. Statements dont.

Let me reiterate. While writing jsx, the dynamic (or javascript) part is written within curly braces({}). And it should always be an expression and it cannot be a statement.

children

When the application grows, there will be multiple levels of component nestings.

const InnerMost = (props) => <div>....</div>
const Inner = (props) => <div>... <InnerMost/> ... </div>
const Outer = (props) => <div>... <Inner/> ... </div>

The above code is not a real one, but just symbolic. Here the point is, ‘Outer’ component contains ‘Inner’ component and which in turn contains ‘InnerMost’ component.

The major problem in this construct is, it is difficult to communicate between ‘Outer’ and ‘InnerMost’ component. Very frequently we may need to pass props to the nested structure. The beginners practice is to pass props to ‘Inner’ component, which in turn will pass to ‘InnerMost’ component. The uncomfortable part in doing so is, the ‘Inner’ component doesn’t require or use the props and it just passes on to its child component. And this unnecessary ‘passing’ can be avoiding by using ‘props.children’ as below.

const InnerMost = (props) => <div>....</div>
const Inner = (props) => <div>... {props.children} ... </div>
const Outer = (props) => (
  <div>
    ... 
    <Inner> 
      ...<InnerMost/> ... 
    </Inner> 
    ... 
  </div>
)

This construct may look a little less intuitive for beginners, but one will find it very comfortable after putting to use for a while.

Discover and read more posts from Rethna
get started