⬆️ ⬇️

JSX: antipattern or not?

Quite often we hear that React and especially JSX templates are bad, and a good developer does not do that. However, it does n’t often explain how it is that the mixing of typesetting and templates in one file hurts. And with this we will try to figure it out today.



The approach of “each technology has its own file” has been used since the beginning of the web, so it’s not surprising that scrapping this pattern causes rejection of some developers. But before declaring “no, we will never do it this way”, it will be useful to understand the history and understand why you can use JSX, but not to mix scripts and html.





Story



From the very beginning, the Web consisted only of static HTML pages. You opened the address, the server returned the page content. Layout, styles, scripts - everything was in the general heap.



However, as sites became more complex, there was a need to reuse styles and scripts on different pages. Over time, the approach of "CSS and JS apart from HTML" has become a general recommendation. Especially under the condition that HTML is generated by the server engine, unlike CSS and JS files, which change only during development and are sent to the server as it is. Separating content into static and dynamic allows the user to download less data due to caching, and the developer is more comfortable editing static files rather than looking for pieces of Javascript in the templates used by the CMS.



Over time, more and more one-page web applications began to appear, where the main part of the logic is focused on the client side. The server sends the same static HTML to any URL, and the Javascript code in the user's browser determines the current address and makes a request to the server for the necessary data. When you click on a link, the page does not reload entirely, but only the URL is updated, and the Javascript code makes a new request for the next page.



The emergence of web applications has radically changed the approach to development. There are new special frameworks designed to create web applications with a large amount of code and complex user interface logic. Data rendering now takes place on the client; in the page resources static html templates are stored, which are pulled over data received from the server.



The component approach has become the most appropriate way to organize such a mass of code. Each more or less independent block is formed into a separate component, with its own styles, pattern and Javascript, and then the whole page is assembled from these blocks.



This approach is implemented by most modern JS frameworks, but with one difference: Angular, Ember and Marionette encourage the creation of a separate file with a template, and React suggests writing HTML inside JS. And it becomes a red rag for some developers.



Template and component



And what is the point of creating a separate file with a template? It is often argued: to separate different entities, because it is so correct . Although historically the reason for the separation of HTML and JS was the separation of statics and dynamics, which is irrelevant for rendering on the client.



So, how much is the component and its template different? Take a snippet of code





Lines show relationships in which changes to a change in one file are affected by another. If it were a connection between two JS modules, the refactoring suggests itself. But for the view and the template do not do that, because it is wrong .



Some time ago, in other conditions, mixing HTML and JS was undesirable, and until now developers blindly follow that rule. But when rendering on the client, the situation is different; besides, initially it was recommended to render JS from HTML, but not HTML from JS.



And how much does it harm in a real project? Let's try an experiment and combine the template with JS:



import Marionette from 'backbone.marionette';
import {warningText} from '../constants';

export default Marionette.ItemView.extend({
  template(templateData) {
    const {title, img_url, count} = templateData;
    const isSelected = this.model.isSelected();
    const isOverLimit = this.model.get('count') > this.model.get('maxAvailable')
    return `<div class="cart-item ${isSelected ? 'active' : ''}">
      <h3>${title}</h3>
      <img src="http://${img_url}" />
      <div>
        <button class="btn-less">-</button>
        <input value="${count}" />
        <button class="btn-more" ${isOverLimit ? 'disabled': ''}>+</button>
      </div>
      ${isOverLimit ? warningText : ''}
    </div>`;
  },
  events: {
    'click btn-less': 'onLessClick',
    'click btn-more': 'onMoreClick'
  }
});


EcmaScript6 template strings, . HTML . , , .



React? , , . , , HTML .



')

Source: https://habr.com/ru/post/311226/



All Articles