ReactJS - cloneElement() Function



React is a well-known JavaScript library for creating user interfaces. It includes a number of features that help us to create flexible and maintainable code. CloneElement is one of these tools, and it allows us to create a new React element based on a prior one while modifying its properties and children. So let's look at what cloneElement is and how to use it.

What is cloneElement?

The term cloneElement is a React method that allows us to create a new React element by using an existing one. This is useful when we want to update the properties of an element or add children to it without changing the original.

Syntax

const clonedElement = cloneElement(elem, props, ...children)

Parameters

  • elem − This is a valid React element, like a JSX node or the result of another cloneElement call.

  • props − It is an object or null that allows us to override the properties of the element. If we pass null, the cloned element keeps all the original props.

  • ...children − There are zero or more child nodes. They can be any React nodes, such as elements, strings, or numbers. If we don't pass any children, the original children will be used.

Return Value

The function cloneElement returns a React element object with the following properties −

  • type − The same as element.type.

  • props − A combination of element.props and the overriding props.

  • ref − The original ref, unless overridden by props.ref.

  • key − The original key, unless overridden by props.key.

The most common use of cloneElement is to override an element's properties. If we have an existing element and want to update particular features, we can simply do so using cloneElement.

Examples

Example − Add a new Prop and Button

In this app we will first import the necessary modules from the 'react' library. cloneElement is imported to make modifications to the basic React element. Now we will create a basic React element using JSX. This element is a simple <div> with text content. Define the App functional component. Inside this component we will use cloneElement to create a modified version of the basicElement. The modification involves adding a new prop called newProp with the value 'Added prop value'.

import React, { cloneElement } from 'react';

const basicElement = <div>This is a basic React element.</div>;
const App = () => {
   const modifiedElement = cloneElement(basicElement, { newProp: 'Added prop value' });
   return (
   <div>
   {modifiedElement}
   <button onClick={() => alert('Button clicked!')}>Click me</button>
   </div>
   );
};

export default App;

Output

basic react element

When we use this component in our React application, it will render the modified element along with a button. Clicking the button will display an alert saying 'Button clicked!'.

Example − Add List of Items

In this example we will first import the necessary modules from the 'react' library. And also cloneElement is imported to make modifications to the basic React element. Now we will have a basic React Element using JSX. This element is a simple <div> with the text content 'This is a basic React element.' And then define the App functional component. Inside this component we will define an array of items. And we will use cloneElement to create a modified version of the basicElement. The modification involves adding a paragraph (<p>) and an unordered list (<ul>) containing list items generated by mapping through the items array.

import React, { cloneElement } from 'react';

const basicElement = <div>This is a basic React element.</div>;
const App = () => {
   const items = ['Item 1', 'Item 2', 'Item 3'];
   const modifiedElement = cloneElement(basicElement, null,
   <>
      <p>List of Items:</p>
      <ul>
         {items.map((item, index) => (
            <li key={index}>{item}</li>
         ))}
      </ul>
   </>
   );
   return <div>{modifiedElement}</div>;
};

export default App;

Output

list of items

When we use this component in our React application, it will render the modified element showing a paragraph and an unordered list of items.

Example − Let’s create an application using cloneElement

In this app, we will create a simple React app that uses the cloneElement to highlight a specific item in a list of items. The app consists of two components: a List component and a Row component, with a parent App component that shows a product list.

  • List Component − It receives a list of children components. Maintains the selectedIndex state to track the currently highlighted item. Iterates over the children using Children.map and uses cloneElement to modify the isHighlighted prop based on the selectedIndex.

  • Row Component − It renders a product title as a row. And applies a CSS class for highlighting if the isHighlighted prop is true.

  • data.js Module − It defines an array of product objects.

  • App.js − In this file we will import the List and Row components along with the product data. And also renders the product list using the List component.

List.js

import { Children, cloneElement, useState } from 'react';

export default function List({ children }) {
   const [selectedIndex, setSelectedIndex] = useState(0);
   
   return (
   <div className="List">
      {Children.map(children, (child, index) =>
         cloneElement(child, {
            isHighlighted: index === selectedIndex,
         })
      )}
      <hr />
      <button
         onClick={() => {
            setSelectedIndex((i) => (i + 1) % Children.count(children));
         }}
      >
         Next
      </button>
   </div>
   );
}

Row.js

export default function Row({ title, isHighlighted }) {
   return (
      <div className={['Row', isHighlighted ? 'RowHighlighted' : ''].join(' ')}>
         {title}
      </div>
   );
}

Data.js

export const products = [
   { title: 'Laptop', id: 1 },
   { title: 'Smartphone', id: 2 },
   { title: 'Headphones', id: 3 },
   { title: 'Tablet', id: 4 },
];

App.js

import List from "./List.js";
import Row from "./Row.js";
import { products } from "./data.js";

export default function App() {
   return (
      <List>
         {products.map((product) => (
            <Row key={product.id} title={product.title} />
         ))}
      </List>
   );
}

Output

cloneElement

Summary

So cloneElement is a useful function in React, it is typically used and might add complexity and problems to our program. Understanding when to use cloneElement and when to use other techniques in our React applications can help us write cleaner and more efficient code.

reactjs_reference_api.htm
Advertisements