Skip to content
Related Articles

Related Articles

How to use custom JSX elements ?

View Discussion
Improve Article
Save Article
Like Article
  • Last Updated : 28 Feb, 2022

JSX is an extension of the JavaScript language which is useful to write React applications. JSX consist of tags, attribute, and children. We can also create our own custom elements in React.

A custom element gives us a new HTML tag in the JSX file that we can be controlled through a native browser API.

Creating React Application

Step 1: Create a React application using the following command:

npx create-react-app example

Step 2: After creating your project folder i.e. example, move to it using the following command:

cd example

Step 3: Create a folder component inside an src folder of reacting project directory and inside the components folder create files Counter.jsx and ImperativeCounter.jsx

Project Structure: It will look like the following.

Example: Write down the following code in Index.js, App.js, Counter.jsx and ImperativeCounter.jsx

Index.js




import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import "./components/ImperativeCounter";
import reportWebVitals from './reportWebVitals';
  
ReactDOM.render(
    <React.StrictMode>
        <App />
    </React.StrictMode>,
    document.getElementById('root')
);


App.js




import React from 'react';
import Counter from './components/Counter';
  
function App() {
    return (
        <div className="App">
            <Counter />
        </div>
    );
}
  
export default App;


Counter.jsx




import React, { useRef } from 'react'
  
function Counter() {
  
    const counterElement = useRef(null);
  
    const incrementCounters = () => {
  
        // Increment the imperative counter
        counterElement.current.increment();
    }
  
    const decrementCounters = () => {
  
        // Decrement the imperative counter
        counterElement.current.decrement();
    }
  
    return (
        <div>
            <div>
                <h5>Imperative Counter</h5>
                <i-counter ref={counterElement}>
                </i-counter>
            </div>
            <button
                onClick={incrementCounters}
                className="btn btn-primary">
                    Increment
                </button>
            <button
                onClick={decrementCounters}
                className="btn btn-primary">
                    Decrement
                </button>
        </div>
    )
}
  
export default Counter


ImperativeCounter.jsx




class ImperativeCounter extends HTMLElement {
    constructor() {
        super();
        this.shadow = this.attachShadow({ mode: 'open' });
        this.currentCount = 0;
        this.update();
    }
  
    update() {
        const template = `
        <style>
          .counter {
            font-size: 25px;
          }
        </style>
        <div class="counter">
          <b>Count:</b> ${this.currentCount}
        </div>
      `;
        this.shadow.innerHTML = template;
    }
  
    increment() {
        this.currentCount++;
        this.update();
    }
  
    decrement() {
        this.currentCount--;
        this.update();
    }
}
  
window.customElements.define('i-counter', ImperativeCounter);


Initially, what we have to do is to define and form a custom element. To do so we create a class that extends the HTMLElement class and then give the name of the element with customElements.define().

Javascript




class ImperativeCounter extends HTMLElement {
    // lines of code
}
window.customElements.define('i-counter', ImperativeCounter);


Now, Since we have set up and defined the custom element we can use it.

We can do much more with the custom element in react. We have three methods to expand the functionality of this element created using custom. There are two lifecycle-like methods that are useful to us are the disconnectedCallBack and the connectedCallback and since this is a class, it comes with a constructor.

Constructor: An instance of the element being created or upgraded. Useful for initializing state, settings up event listeners, or creating Shadow DOM. See the spec for restrictions on what you can do in the constructor.

connectedCallback: The element is inserted into the DOM. Useful for running setup code, such as fetching resources or rendering UI. Generally, you should try to delay work until this time

disconnectedCallback: When the element is removed from the DOM. Useful for running clean-up code.

Let’s make a custom element with attributes. 

Javascript




class ImperativeCounter extends HTMLElement {
    constructor() {
        super();
        this.shadow = this.attachShadow({ mode: 'open' });
        this.currentCount = 0;
        this.update();
    }
}
  
window.customElements.define('i-counter', ImperativeCounter);


Now, we will add a function to this class to update, increment and decrement.

Javascript




class ImperativeCounter extends HTMLElement {
    constructor() {
        super();
        this.shadow = this.attachShadow({ mode: 'open' });
        this.currentCount = 0;
        this.update();
    }
  
    update() {
        const template = `
        <style>
          .counter {
            font-size: 25px;
          }
        </style>
        <div class="counter">
          <b>Count:</b> ${this.currentCount}
        </div>
      `;
        this.shadow.innerHTML = template;
    }
  
    increment() {
        this.currentCount++;
        this.update();
    }
  
    decrement() {
        this.currentCount--;
        this.update();
    }
}
  
window.customElements.define('i-counter', ImperativeCounter);


Javascript




class profile extends HTMLElement {
    constructor() {
        super();
  
        this.profileDetails = null;
  
        this.name = this.getAttribute("name");
        this.endpoint = 
            `https://api.github.com/repos/${this.name}`
        this.innerHTML = `<h1>Loading</h1>`
    }
    async getDetails() {
        return await fetch(this.endpoint, 
        { mode: "cors" }).then(res => res.json());
    }
}


Finally, we have created the custom element <i-counter ref={counterElement}></i-counter> and now we can use it in our jsx aap.

Step to Run Application: Run the application using the following command from the root directory of the project:

npm start

Output:

Output

There we have created a custom element that manages its own state and reflects that state back to the user while giving us an HTML element to use in our JSX.


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!