⬆️ ⬇️

Is it possible to do without jsx and why?

I’m sure most of you who use react use jsx . Thanks to its laconic syntax, jsx improves template readability. Compare:



render() { return React.createElement('div', { className: 'block'}, 'Text of block'); } // vs render() { return <div className='block'> Text of block </div>; } 


The second option, even in such a simple example, looks much clearer. To complicate the example, the difference will be even more obvious.



What is bad jsx



It would be nice if jsx were a standard javascript feature, but this is not true. To work with jsx you need a transpiler. If you decide to use jsx, you will forever become addicted to transpilation. Not so long ago, such a relationship did not frighten anyone, because in order to use the new features from ecmascript 2015 you need a transpiler anyway. But everything changes, the es6 support level is close to 100%



At least, in the develop-environment it is already possible to get rid of transpilation. Can you imagine what opportunities this opens up? You do not need to dig into the output of babel during debugging, which has changed a lot, source map is not needed, after changing the file there is no need to wait until the reassembly is over. And jsx in this case will be the main obstacle ... Are there alternatives to jsx ?



Alternatives to jsx



The ecmascript 2015 standard defines tagged template strings . The example above can be rewritten as:



 render() { return es6x `<div className='block'> Text of block </div>`; } 


More complicated example:



 import Input from './input'; render() { return <div className='block'> <Input name='name1' value={this.props.value} {...this.props.inputProps} checked /> {this.props.items.map(item => <span {...item.props}>{item.text}</span>} </div>; } //  : render() { return es6x `<div className='block'> <${Input} name='name1' value=${this.props.value} ${this.props.inputProps} checked /> ${this.props.items.map(item => es6x `<span ${item.props}>${item.text}</span>`)} </div>`; } 


How to connect



 npm install --save es6x 


The es6x package supports different engines. Among them are react , hyperscript (h), and (by default) universal output in json of the form:



 { tag: 'div', attrs: { className: 'block' }, children: ['Text of block'] } 


To use together with react, you must specify the output method before the first call (in one place of the project):



 import React from 'react'; import es6x from 'es6x'; es6x.setOutputMethod(React.createElement); 


Es6x Package Features





 return <div> {'some text'} {' '} <b>strong</b> {' '} <i>emphase</i> </div> 


In the example above, in jsx you need to add an ugly construction {''} between the words "text", "strong" and "emphase" and in es6x this is not required:



 return es6x `<div> ${'some text'} <b>strong</b> <i>emphase</i> </div>`; 


Performance



es6x supports caching, so that when you call again with the same template, no parsing occurs and the call is much faster. Recalling the test results 10 times faster than the first (in the case of universal parsing in json, in the case of parsing for react, the difference is less - less than 2 times). I also made a comparison with the t7 competitive package when parsing for react . Results:



jsx output: 15683 ops / sec ± 1%

es6x: 11187 ops / sec ± 1%

t7: 10253 ops / sec ± 1% (does not support many jsx buns)



That is a drop in performance of about 30%. What turned out less than I expected. It is explained by the fact that the createElement method is rather heavy.



Use, inform me about bugs. Thank you all for your attention.



')

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



All Articles