JSX (Javascript XML)

JSX is a syntax extension for JavaScript that allows you to write HTML-like code within your JavaScript files. It stands for JavaScript XML. JSX makes it easier to write and understand React components by blending HTML and JavaScript syntax together.

Why JSX ?

JSX simplifies the process of building user interfaces in React by providing a more expressive and readable syntax. Instead of writing separate JavaScript and HTML code, JSX allows you to write both in a single file, making it easier to visualize and understand the component’s structure.

Basic JSX Syntax

Embedding Expressions

In JSX, you can embed JavaScript expressions using curly braces {}. This allows you to dynamically insert values or execute JavaScript code within your JSX code.

				
					const name = "John";
const element = <h1>Hello, {name}</h1>;

				
			

Explanation

  • In the example above, {name} is a JavaScript expression embedded within JSX.
  • When the JSX is rendered, {name} is replaced with the value of the name variable, resulting in the text “Hello, John” being rendered inside the <h1> element.

Using JSX Elements

JSX elements look similar to HTML tags, but they are actually objects that represent React elements. You can use JSX elements to build the UI structure of your React components.

				
					const element = <div>Hello, React!</div>;

				
			

Explanation

  • <div>Hello, React!</div> is a JSX element representing a <div> element with the text “Hello, React!” inside it.
  • JSX elements can contain other JSX elements, allowing you to create nested structures to represent your UI.

Rendering JSX

To render JSX elements in your React application, you can use ReactDOM’s render() method.

				
					import React from 'react';
import ReactDOM from 'react-dom';

const element = <h1>Hello, React!</h1>;
ReactDOM.render(element, document.getElementById('root'));

				
			

Explanation

  • In this example, we import React and ReactDOM at the top of the file.
  • We create a JSX element <h1>Hello, React!</h1> and store it in the element variable.
  • We use ReactDOM.render() to render the element onto the DOM. The render() method takes two arguments: the JSX element to render and the DOM element where it should be rendered (document.getElementById('root')).

JSX Attributes and Props

In React, JSX elements can have attributes just like HTML elements. These attributes are used to pass additional information to the elements or customize their behavior. Props (short for properties) are a way to pass data from parent to child components in React.

Adding Attributes

In JSX, you can add attributes to elements using the same syntax as HTML. However, JSX attributes are camelCase instead of lowercase.

				
					const element = <input type="text" placeholder="Enter your name" />;

				
			

Explanation

  • In the example above, we create an <input> element with two attributes: type and placeholder.
  • The type attribute specifies the type of the input field, while the placeholder attribute provides a hint to the user about what to enter in the input field.
  • When the JSX is rendered, it will be converted into HTML with these attributes intact.

Using Props

Props allow you to pass data from parent to child components in React. You can pass props to JSX elements by specifying them as attributes.

				
					function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

const element = <Welcome name="John" />;

				
			

Explanation

  • In this example, we define a functional component named Welcome that takes a props object as its argument.
  • Inside the component, we access the name prop using props.name and render it within an <h1> element.
  • When we render the Welcome component, we pass the name prop as an attribute with the value "John".
  • The value of the name prop is dynamically inserted into the JSX element when it is rendered.

Full Code Example

				
					// App.js or Index.js
import React from 'react';
import ReactDOM from 'react-dom';

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

const element = <Welcome name="John" />;

ReactDOM.render(element, document.getElementById('root'));

				
			

Explanation

  • We import React and ReactDOM at the top of the file to use React and render React components onto the DOM.
  • We define a functional component named Welcome that takes a props object as its argument. Inside the component, we access the name prop using props.name and render it within an <h1> element.
  • We create a JSX element <Welcome name="John" />, where we pass the name prop with the value "John".
  • We use ReactDOM.render() to render the element onto the DOM. The rendered output will replace the content of the HTML element with the ID root.
				
					// index.html 
<div id="root">
  <h1>Hello, John</h1>
</div>

				
			

Explanation

  • The Welcome component is rendered with the name prop set to “John“.
  • The text “Hello, John” is displayed inside an <h1> element on the webpage.

Advanced JSX Features

Conditional Rendering

Conditional rendering allows you to display different JSX elements based on certain conditions. This is commonly used to render different content based on the state of your application.

				
					const isLoggedIn = true;
const element = (
  <div>
    {isLoggedIn ? <p>Welcome, user!</p> : <p>Please log in.</p>}
  </div>
);

				
			

Explanation

  • In this example, we have a variable isLoggedIn that determines whether the user is logged in or not.
  • We use a ternary operator (isLoggedIn ? ... : ...) to conditionally render different JSX elements based on the value of isLoggedIn.
  • If isLoggedIn is true, we render a <p> element with the text “Welcome, user!”. Otherwise, we render a <p> element with the text “Please log in.”.
  • The JSX expression inside the curly braces {} is evaluated dynamically, allowing us to render different content based on the condition.

Mapping Arrays

You can use JavaScript’s map() function to dynamically render lists of JSX elements based on the items in an array. This is useful for rendering dynamic content, such as a list of items fetched from an API.

				
					const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) => <li key={number}>{number}</li>);
const element = <ul>{listItems}</ul>;

				
			

Explanation

  • In this example, we have an array numbers containing a list of numbers.
  • We use the map() function to iterate over each item in the numbers array and return a JSX <li> element for each number. We also provide a unique key prop for each <li> element to help React identify them efficiently.
  • The resulting array of JSX elements (listItems) is then rendered inside a <ul> element, creating a numbered list of items.

Styling with JSX

You can apply inline styles to JSX elements using JavaScript objects. This allows you to dynamically style your components based on props, state, or other factors.

				
					const style = {
  color: 'blue',
  fontSize: '20px',
};

const element = <p style={style}>Styled Text</p>;

				
			

Explanation

  • In this example, we define a JavaScript object style containing CSS properties and values.
  • We use the style object as an attribute in the JSX element <p style={style}>.
  • The CSS properties in the style object are camelCased, just like in regular CSS, but they are specified as strings in the JavaScript object.
  • React will apply the styles defined in the style object to the <p> element when it is rendered.

Lets see an example considering all above examples

				
					// project structure 
my-react-app/
├── node_modules/
├── public/
│   ├── index.html
│   └── favicon.ico
├── src/
│   ├── components/
│   │   └── App.js
│   ├── App.css
│   ├── index.js
│   └── logo.svg
├── .gitignore
├── package-lock.json
├── package.json
└── README.md

				
			

1. src/components/App.js:

				
					import React from 'react';
import './App.css';

function App() {
  const isLoggedIn = true;
  const numbers = [1, 2, 3, 4, 5];

  return (
    <div className="App">
      <h1>Welcome to My React App!</h1>
      
      {/* Conditional Rendering */}
      {isLoggedIn ? <p>Welcome, user!</p> : <p>Please log in.</p>}

      {/* Mapping Arrays */}
      <ul>
        {numbers.map((number) => (
          <li key={number}>{number}</li>
        ))}
      </ul>

      {/* Styling with JSX */}
      <p style={{ color: 'blue', fontSize: '20px' }}>Styled Text</p>
    </div>
  );
}

export default App;

				
			

2. src/App.css:

				
					.App {
  text-align: center;
  margin-top: 50px;
}

ul {
  list-style-type: none;
  padding: 0;
}

ul li {
  margin-bottom: 10px;
}

				
			

3. src/index.js:

				
					import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

				
			

4. public/index.html:

				
					<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>My React App</title>
</head>
<body>
  <div id="root"></div> <script data-no-optimize="1">!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).LazyLoad=e()}(this,function(){"use strict";function e(){return(e=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n,a=arguments[e];for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(t[n]=a[n])}return t}).apply(this,arguments)}function i(t){return e({},it,t)}function o(t,e){var n,a="LazyLoad::Initialized",i=new t(e);try{n=new CustomEvent(a,{detail:{instance:i}})}catch(t){(n=document.createEvent("CustomEvent")).initCustomEvent(a,!1,!1,{instance:i})}window.dispatchEvent(n)}function l(t,e){return t.getAttribute(gt+e)}function c(t){return l(t,bt)}function s(t,e){return function(t,e,n){e=gt+e;null!==n?t.setAttribute(e,n):t.removeAttribute(e)}(t,bt,e)}function r(t){return s(t,null),0}function u(t){return null===c(t)}function d(t){return c(t)===vt}function f(t,e,n,a){t&&(void 0===a?void 0===n?t(e):t(e,n):t(e,n,a))}function _(t,e){nt?t.classList.add(e):t.className+=(t.className?" ":"")+e}function v(t,e){nt?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\s+)"+e+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")}function g(t){return t.llTempImage}function b(t,e){!e||(e=e._observer)&&e.unobserve(t)}function p(t,e){t&&(t.loadingCount+=e)}function h(t,e){t&&(t.toLoadCount=e)}function n(t){for(var e,n=[],a=0;e=t.children[a];a+=1)"SOURCE"===e.tagName&&n.push(e);return n}function m(t,e){(t=t.parentNode)&&"PICTURE"===t.tagName&&n(t).forEach(e)}function a(t,e){n(t).forEach(e)}function E(t){return!!t[st]}function I(t){return t[st]}function y(t){return delete t[st]}function A(e,t){var n;E(e)||(n={},t.forEach(function(t){n[t]=e.getAttribute(t)}),e[st]=n)}function k(a,t){var i;E(a)&&(i=I(a),t.forEach(function(t){var e,n;e=a,(t=i[n=t])?e.setAttribute(n,t):e.removeAttribute(n)}))}function L(t,e,n){_(t,e.class_loading),s(t,ut),n&&(p(n,1),f(e.callback_loading,t,n))}function w(t,e,n){n&&t.setAttribute(e,n)}function x(t,e){w(t,ct,l(t,e.data_sizes)),w(t,rt,l(t,e.data_srcset)),w(t,ot,l(t,e.data_src))}function O(t,e,n){var a=l(t,e.data_bg_multi),i=l(t,e.data_bg_multi_hidpi);(a=at&&i?i:a)&&(t.style.backgroundImage=a,n=n,_(t=t,(e=e).class_applied),s(t,ft),n&&(e.unobserve_completed&&b(t,e),f(e.callback_applied,t,n)))}function N(t,e){!e||0<e.loadingCount||0<e.toLoadCount||f(t.callback_finish,e)}function C(t,e,n){t.addEventListener(e,n),t.llEvLisnrs[e]=n}function M(t){return!!t.llEvLisnrs}function z(t){if(M(t)){var e,n,a=t.llEvLisnrs;for(e in a){var i=a[e];n=e,i=i,t.removeEventListener(n,i)}delete t.llEvLisnrs}}function R(t,e,n){var a;delete t.llTempImage,p(n,-1),(a=n)&&--a.toLoadCount,v(t,e.class_loading),e.unobserve_completed&&b(t,n)}function T(o,r,c){var l=g(o)||o;M(l)||function(t,e,n){M(t)||(t.llEvLisnrs={});var a="VIDEO"===t.tagName?"loadeddata":"load";C(t,a,e),C(t,"error",n)}(l,function(t){var e,n,a,i;n=r,a=c,i=d(e=o),R(e,n,a),_(e,n.class_loaded),s(e,dt),f(n.callback_loaded,e,a),i||N(n,a),z(l)},function(t){var e,n,a,i;n=r,a=c,i=d(e=o),R(e,n,a),_(e,n.class_error),s(e,_t),f(n.callback_error,e,a),i||N(n,a),z(l)})}function G(t,e,n){var a,i,o,r,c;t.llTempImage=document.createElement("IMG"),T(t,e,n),E(c=t)||(c[st]={backgroundImage:c.style.backgroundImage}),o=n,r=l(a=t,(i=e).data_bg),c=l(a,i.data_bg_hidpi),(r=at&&c?c:r)&&(a.style.backgroundImage='url("'.concat(r,'")'),g(a).setAttribute(ot,r),L(a,i,o)),O(t,e,n)}function D(t,e,n){var a;T(t,e,n),a=e,e=n,(t=It[(n=t).tagName])&&(t(n,a),L(n,a,e))}function V(t,e,n){var a;a=t,(-1<yt.indexOf(a.tagName)?D:G)(t,e,n)}function F(t,e,n){var a;t.setAttribute("loading","lazy"),T(t,e,n),a=e,(e=It[(n=t).tagName])&&e(n,a),s(t,vt)}function j(t){t.removeAttribute(ot),t.removeAttribute(rt),t.removeAttribute(ct)}function P(t){m(t,function(t){k(t,Et)}),k(t,Et)}function S(t){var e;(e=At[t.tagName])?e(t):E(e=t)&&(t=I(e),e.style.backgroundImage=t.backgroundImage)}function U(t,e){var n;S(t),n=e,u(e=t)||d(e)||(v(e,n.class_entered),v(e,n.class_exited),v(e,n.class_applied),v(e,n.class_loading),v(e,n.class_loaded),v(e,n.class_error)),r(t),y(t)}function $(t,e,n,a){var i;n.cancel_on_exit&&(c(t)!==ut||"IMG"===t.tagName&&(z(t),m(i=t,function(t){j(t)}),j(i),P(t),v(t,n.class_loading),p(a,-1),r(t),f(n.callback_cancel,t,e,a)))}function q(t,e,n,a){var i,o,r=(o=t,0<=pt.indexOf(c(o)));s(t,"entered"),_(t,n.class_entered),v(t,n.class_exited),i=t,o=a,n.unobserve_entered&&b(i,o),f(n.callback_enter,t,e,a),r||V(t,n,a)}function H(t){return t.use_native&&"loading"in HTMLImageElement.prototype}function B(t,i,o){t.forEach(function(t){return(a=t).isIntersecting||0<a.intersectionRatio?q(t.target,t,i,o):(e=t.target,n=t,a=i,t=o,void(u(e)||(_(e,a.class_exited),$(e,n,a,t),f(a.callback_exit,e,n,t))));var e,n,a})}function J(e,n){var t;et&&!H(e)&&(n._observer=new IntersectionObserver(function(t){B(t,e,n)},{root:(t=e).container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}))}function K(t){return Array.prototype.slice.call(t)}function Q(t){return t.container.querySelectorAll(t.elements_selector)}function W(t){return c(t)===_t}function X(t,e){return e=t||Q(e),K(e).filter(u)}function Y(e,t){var n;(n=Q(e),K(n).filter(W)).forEach(function(t){v(t,e.class_error),r(t)}),t.update()}function t(t,e){var n,a,t=i(t);this._settings=t,this.loadingCount=0,J(t,this),n=t,a=this,Z&&window.addEventListener("online",function(){Y(n,a)}),this.update(e)}var Z="undefined"!=typeof window,tt=Z&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),et=Z&&"IntersectionObserver"in window,nt=Z&&"classList"in document.createElement("p"),at=Z&&1<window.devicePixelRatio,it={elements_selector:".lazy",container:tt||Z?document:null,threshold:300,thresholds:null,data_src:"src",data_srcset:"srcset",data_sizes:"sizes",data_bg:"bg",data_bg_hidpi:"bg-hidpi",data_bg_multi:"bg-multi",data_bg_multi_hidpi:"bg-multi-hidpi",data_poster:"poster",class_applied:"applied",class_loading:"litespeed-loading",class_loaded:"litespeed-loaded",class_error:"error",class_entered:"entered",class_exited:"exited",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!0,callback_enter:null,callback_exit:null,callback_applied:null,callback_loading:null,callback_loaded:null,callback_error:null,callback_finish:null,callback_cancel:null,use_native:!1},ot="src",rt="srcset",ct="sizes",lt="poster",st="llOriginalAttrs",ut="loading",dt="loaded",ft="applied",_t="error",vt="native",gt="data-",bt="ll-status",pt=[ut,dt,ft,_t],ht=[ot],mt=[ot,lt],Et=[ot,rt,ct],It={IMG:function(t,e){m(t,function(t){A(t,Et),x(t,e)}),A(t,Et),x(t,e)},IFRAME:function(t,e){A(t,ht),w(t,ot,l(t,e.data_src))},VIDEO:function(t,e){a(t,function(t){A(t,ht),w(t,ot,l(t,e.data_src))}),A(t,mt),w(t,lt,l(t,e.data_poster)),w(t,ot,l(t,e.data_src)),t.load()}},yt=["IMG","IFRAME","VIDEO"],At={IMG:P,IFRAME:function(t){k(t,ht)},VIDEO:function(t){a(t,function(t){k(t,ht)}),k(t,mt),t.load()}},kt=["IMG","IFRAME","VIDEO"];return t.prototype={update:function(t){var e,n,a,i=this._settings,o=X(t,i);{if(h(this,o.length),!tt&&et)return H(i)?(e=i,n=this,o.forEach(function(t){-1!==kt.indexOf(t.tagName)&&F(t,e,n)}),void h(n,0)):(t=this._observer,i=o,t.disconnect(),a=t,void i.forEach(function(t){a.observe(t)}));this.loadAll(o)}},destroy:function(){this._observer&&this._observer.disconnect(),Q(this._settings).forEach(function(t){y(t)}),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(t){var e=this,n=this._settings;X(t,n).forEach(function(t){b(t,e),V(t,n,e)})},restoreAll:function(){var e=this._settings;Q(e).forEach(function(t){U(t,e)})}},t.load=function(t,e){e=i(e);V(t,e)},t.resetStatus=function(t){r(t)},Z&&function(t,e){if(e)if(e.length)for(var n,a=0;n=e[a];a+=1)o(t,n);else o(t,e)}(t,window.lazyLoadOptions),t});!function(e,t){"use strict";function a(){t.body.classList.add("litespeed_lazyloaded")}function n(){console.log("[LiteSpeed] Start Lazy Load Images"),d=new LazyLoad({elements_selector:"[data-lazyloaded]",callback_finish:a}),o=function(){d.update()},e.MutationObserver&&new MutationObserver(o).observe(t.documentElement,{childList:!0,subtree:!0,attributes:!0})}var d,o;e.addEventListener?e.addEventListener("load",n,!1):e.attachEvent("onload",n)}(window,document);</script><script data-no-optimize="1">var litespeed_vary=document.cookie.replace(/(?:(?:^|.*;\s*)_lscache_vary\s*\=\s*([^;]*).*$)|^.*$/,"");litespeed_vary||fetch("/wp-content/plugins/litespeed-cache/guest.vary.php",{method:"POST",cache:"no-cache",redirect:"follow"}).then(e=>e.json()).then(e=>{console.log(e),e.hasOwnProperty("reload")&&"yes"==e.reload&&(sessionStorage.setItem("litespeed_docref",document.referrer),window.location.reload(!0))});</script><script data-optimized="1" type="litespeed/javascript" data-src="https://diginode.in/wp-content/litespeed/js/96d0e6d4ba93134cbdab615e06eb2824.js?ver=b26c3"></script><script>const litespeed_ui_events=["mouseover","click","keydown","wheel","touchmove","touchstart"];var urlCreator=window.URL||window.webkitURL;function litespeed_load_delayed_js_force(){console.log("[LiteSpeed] Start Load JS Delayed"),litespeed_ui_events.forEach(e=>{window.removeEventListener(e,litespeed_load_delayed_js_force,{passive:!0})}),document.querySelectorAll("iframe[data-litespeed-src]").forEach(e=>{e.setAttribute("src",e.getAttribute("data-litespeed-src"))}),"loading"==document.readyState?window.addEventListener("DOMContentLoaded",litespeed_load_delayed_js):litespeed_load_delayed_js()}litespeed_ui_events.forEach(e=>{window.addEventListener(e,litespeed_load_delayed_js_force,{passive:!0})});async function litespeed_load_delayed_js(){let t=[];for(var d in document.querySelectorAll('script[type="litespeed/javascript"]').forEach(e=>{t.push(e)}),t)await new Promise(e=>litespeed_load_one(t[d],e));document.dispatchEvent(new Event("DOMContentLiteSpeedLoaded")),window.dispatchEvent(new Event("DOMContentLiteSpeedLoaded"))}function litespeed_load_one(t,e){console.log("[LiteSpeed] Load ",t);var d=document.createElement("script");d.addEventListener("load",e),d.addEventListener("error",e),t.getAttributeNames().forEach(e=>{"type"!=e&&d.setAttribute("data-src"==e?"src":e,t.getAttribute(e))});let a=!(d.type="text/javascript");!d.src&&t.textContent&&(d.src=litespeed_inline2src(t.textContent),a=!0),t.after(d),t.remove(),a&&e()}function litespeed_inline2src(t){try{var d=urlCreator.createObjectURL(new Blob([t.replace(/^(?:<!--)?(.*?)(?:-->)?$/gm,"$1")],{type:"text/javascript"}))}catch(e){d="data:text/javascript;base64,"+btoa(t.replace(/^(?:<!--)?(.*?)(?:-->)?$/gm,"$1"))}return d}</script></body>
</html>

				
			

Output:

When you run the application (npm start), you’ll see the following output in your browser

Explanation:

  • The App component in src/components/App.js demonstrates various React functionalities:

    • Conditional Rendering: Displays different messages based on the isLoggedIn variable.
    • Mapping Arrays: Renders a list of numbers using the map() function.
    • Styling with JSX: Applies inline styles to a paragraph element.
  • The styles for the App component are defined in src/App.css.

  • The index.js file in src is the entry point of the application. It imports the App component and renders it to the DOM.

  • The public/index.html file is the main HTML file where the React application is mounted.

JSX is a powerful feature of React that allows you to write HTML-like code within your JavaScript files. It provides a more expressive and readable syntax for building user interfaces in React applications.Happy coding ! ❤️

Table of Contents