Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
June 5, 2020 02:09 pm GMT

3 Common Misconceptions about JSX

I have personally held the distaste of seeing JSX being used in React. For years, I had very strong opinions against using it until I had no other choice but to learn it.

I want to share 3 misconceptions I had and how I realized that these things were not entirely true when you look at it from a certain point of view.

You're going to find that many of the truths we cling to depend greatly on our own point of view - Obiwan Kenobi

I will not try to preach that JSX has without any flaws. As with other tools, a tool is only as good as how you would use it.

JSX is now being used even outside of React, on projects like MDX, VueJS, and StencilJS. In this blog, I will be focusing on the context of React to explain my thoughts regarding JSX.

No Separation of Concerns

JSX forces us to mix JavaScript and HTML together. This means that it is trying to force us to go against the mantra of Separation of Concerns due to the mixing of layout & logic.

Heres the thing, using JSX to write your presentation code doesnt necessarily mean giving up these principles. Let us look at this very simple component in React

const HelloWorld = ({name}) => {   const message = `Hello ${name}`;   return <h1>{message}</h1>}

Theres no reason why that separation cant occur in the context of JavaScript. In this example the layout & logic is separated like this:

const HelloWorld = ({name}) => {   // component logic is confined above the JSX block   // some logic to form message   const message = `Hello ${name}`;   // JSX is confined to this return block   return <h1>{message}</h1>}

To better understand this, let us now try converting this component into an Angular component.

@Component({  selector: 'hello-world',  // template is confined in this property  template: `<h1>{{message}}</h1>`})export class HelloWorldComponent {  // component logic is confined in this class  message: String;  @Input()  public set name(name: string) {    // some logic to form message    this.message = `Hello {name}`;  }}

On Angular, you can separate the template using files. I will be using MVVM/MVC terms to properly explain what is going on here.

Component Controller

@Component({  selector: 'hello-world',  templateUrl: './hello-world.html',})...

Component View

<h1>{{message}}</h1>

You may say that the template/layout example above is so simple so it doesn't really show the dark side of JSX. We could switch it up a bit by throwing it in a condition.

JSX

{render && <h1>{message}</h1>}

Angular Template

<h1 *ngIf="render">{{message}}</h1>

As you can see above they are just about the same, JSX using JavaScript & HTML, while Angular introducing *ngIf.

In this case, the conditional logic is actually mixed with the layout on both examples. Be it separated by JavaScript context in React, or separated by files in Angular.

In React, the layout is in the same file as the component. This gives you a clear idea about the component context and what is available at your disposal. However, you will likely have a very long file as time goes by even in Vue SFCs. Luckily, editors nowadays have a way to split the window so that you can work on different sections of the same file.

Even though I have stated here that you can confine JSX to the return part of the component. There is definitely no one stopping you from doing this.

const HelloWorld = ({name}) => {   const message = <h1>{`Hello ${name}`}</h1>;   return message;}

If you have to declare multiple JSX pieces across your component, think of a better way to achieve this using multiple components.

Another Templating Syntax

While JSX is claiming that it's easy to learn it because you can write HTML on JavaScript, we can think that it is actually an abomination of what we have been trying to achieve separating HTML and JavaScript.

On common frontend libraries/frameworks we have actually come up with different solutions to keep the separation between HTML from JavaScript while making HTML dynamic: Angular Template Syntax, VueJS Template Syntax.

Did you notice that there is no such thing as a JSX Template Syntax or a React Template Syntax? This is probably only the page with explains about JSX and it's just very short documentation. It's because JSX is not a templating engine. Though it looks like it, JSX isnt a templating engine, in the sense that Handlebars is a templating engine, similar to what I have linked above.

JSX is actually more than that, it is a syntax extension for JavaScript. Basically, it extends JavaScript so that HTML/XML like structures can be used with JavaScript.

If you actually looked at the documentation I linked above, there is a lot to learn to get started with these templating engines as compared to JSX. In JSX, at the bare minimum, you only need to know JavaScript and HTML and a few extra exceptions. Below is an example of rendering items using a loop in JSX.

<div> {names.map(name => (    <li>      {name}    </li> ))}</div>

Looking at this you only need to know what the JavaScript .map does, HTML div and li and the extra {} for evaluating JavaScript code. I know, this does not look clean at first, it looks an ugly soup of JS mashed with HTML. But, let me walk you through what is happening here.

<div>{}</div>

In JSX, HTML and JS is considered a valid JSX. However, to slap a JS within an HTML you need to make use of {}. Now let us look inside the {}.

names.map(name => (<li>{name}</li>))

This is JavaScript returning a collection of <li/> which is an HTML but is also considered valid JavaScript in JSX.

While we can think that React and JSX go against how templates are done in MVVM/MVC frameworks, that is not entirely true. Here are some templating engines on popular backend frameworks that would look very familiar to you.

Blade Templates (PHP)

<div>@foreach ($name as $names)   <li>{{ $name }}</li>@endforeach</div>

Razor Templates (C#)

<div>@foreach (var name in names){  <li>@name</li>}</div>

Jinja Templates (Python)

<div>{% for name in names %}  <li>{{name}}</li>{% endfor %}</div>

As you can see this is about the same concept in PHP, C#, Python templating engines. You just have to know the language and some extras to actually remember it.

Now let us go back to the frontend. Let us look at the template engine of Handlebars, VueJS, Angular, and see how it looks.

Handlebars

<div>{{#each names}}   <li>{{this}}</li>{{/each}}</div>

VueJS

<div>  <li v-for="name in names">{{name}}<li></div>

Angular

<div>  <li *ngFor="let name of names">{{ hero }}</li></div>

I must admit these look cleaner in my opinion. But, I think once the props or the attributes get into a certain number, it will be harder to identify the scope and context of control structures. You also have to remember a lot of custom attributes. Other than that, it just takes getting used to.

To drive my point home, JSX is not a templating engine but it allows us to do what another templating engine has been doing for years. On top of that, it looks very familiar since you are dealing with JavaScript and HTML.

There are more uses to JSX other than conjuring templates, you can visit the list of links I mentioned in the introduction of this article. If you don't like React, you could still consider using JSX from those projects.

Personally, it was not React that got me started to like JSX. It was StencilJS. When I finally got the hang of it, I finally considered giving React a second chance.

Too Flexible

I agree that this could be a valid rant. As with things that are too flexible, it could easily be abused. On JSX its not only JavaScript and HTML that you should look out for. It can also be used with React components which would make it confusing for someone who doesn't know React.

A React element in JSX is also a function. Hence, JSX can be used to conjure cryptic code such as this

You wouldn't probably be doing this although there could be some use cases for this. While I don't have the actual implementation of this code, this could be using React Context and Render Props under the hood which is specifically what React provides.

If you are looking into JSX, obviously you will be looking into React and wonder what Render Props are. I don't want to turn this into a React course but would just try to make a point by showing how Render Props work.

I want to create a generic Mouse component that outputs the x and y coordinates of the mouse within the component. I can then display the x and y coordinate in whatever way I like. So this is how we do it in React using Render Props.

Mouse React Component

const Mouse = ({children, onMouseMove}) => {  const [coords, setCoords] = useState({x:0,y:0});  const onMouseMove = (event) {    setCoords({x: event.clientX, y: event.clientY});  }  return (<div onMouseMove={onMouseMove}>     children({       x: coords.x,        y: coords.y     })  </div>)}

Use Mouse Component (React)

<Mouse>  ({x,y}) => {     return <h1>The mouse position is ({x}, {y})</h1>  }</Mouse>

In this example, we can see that the Mouse component accepts a function and it invokes that function on its JSX block. The function which is passed also returns a JSX.

This is somewhat similar to how high order functions work in JavaScript. A higher-order function is a function that takes a function as an argument or returns a function

Let us now try to do this in Angular.

Mouse Angular Component

@Component({  selector: 'mouse',  template: `  <div (mousemove)="handleMouseMove($event)">    <ng-container *ngTemplateOutlet="template; context: coords" ></ng-container>  </div>  `,})export class Mouse {  @ContentChild(TemplateRef) template;  coords = { x: 0, y: 0 }  handleMouseMove(event) {    this.coords = {      x: event.clientX,      y: event.clientY    }  }}

Use Mouse Component (Angular)

<mouse>  <ng-template let-x="x" let-y="y">     <h1>The mouse position is ({{x}}, {{y}})</h1>  </ng-template></mouse>

I can actually say that this is much harder to understand if I don't know what ng-template, ng-container, and TempalateRefare and how they actually work. With JSX, we were able to achieve what we like with shorter succinct code.

Conclusion

There is actually nothing compelling about what Ive done here several technologies have been using some sort of templating engine for quite some time. I still like working with templates even though I have been working with JSX nowadays.

Maybe we should start using something for a considerable amount of time before actually hating it. The use of templates vs JSX, highly depends on what application you are building, your teams preferences, experience, or perhaps whether or not you have code-capable designers on your team.

What do you like or don't like about JSX? Please share your thoughts.


Original Link: https://dev.to/geocine/3-common-misconceptions-about-jsx-3di7

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To