ReactJS - cloneElement() 函式



React 是一個著名的 JavaScript 庫,用於建立使用者介面。它包含許多特性,可以幫助我們建立靈活且易於維護的程式碼。cloneElement 就是這些工具之一,它允許我們基於之前的 React 元素建立一個新的 React 元素,同時修改其屬性和子元素。因此,讓我們瞭解一下 cloneElement 是什麼以及如何使用它。

什麼是 cloneElement?

cloneElement 是一個 React 方法,允許我們使用現有的 React 元素建立一個新的 React 元素。當我們想要更新元素的屬性或向其新增子元素而無需更改原始元素時,這非常有用。

語法

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

引數

  • elem − 這是一個有效的 React 元素,例如 JSX 節點或另一個 cloneElement 呼叫的結果。

  • props − 它是一個物件或 null,允許我們覆蓋元素的屬性。如果我們傳遞 null,則克隆的元素保留所有原始 props。

  • ...children − 有零個或多個子節點。它們可以是任何 React 節點,例如元素、字串或數字。如果我們不傳遞任何子節點,則將使用原始子節點。

返回值

cloneElement 函式返回一個具有以下屬性的 React 元素物件:

  • type − 與 element.type 相同。

  • props − element.props 和覆蓋的 props 的組合。

  • ref − 原始 ref,除非被 props.ref 覆蓋。

  • key − 原始 key,除非被 props.key 覆蓋。

cloneElement 最常見的用途是覆蓋元素的屬性。如果我們有一個現有的元素並想要更新特定屬性,我們可以簡單地使用 cloneElement 來實現。

示例

示例 - 新增一個新的 Prop 和按鈕

在這個應用中,我們將首先從 'react' 庫匯入必要的模組。匯入 cloneElement 以對基本的 React 元素進行修改。現在,我們將使用 JSX 建立一個基本的 React 元素。此元素是一個簡單的 <div>,包含文字內容。定義 App 函式式元件。在這個元件中,我們將使用 cloneElement 建立 basicElement 的修改版本。修改包括新增一個名為 newProp 的新 prop,其值為 '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;

輸出

basic react element

當我們在 React 應用中使用此元件時,它將呈現修改後的元素以及一個按鈕。單擊按鈕將顯示一條警報,內容為“Button clicked!”。

示例 - 新增專案列表

在這個示例中,我們將首先從 'react' 庫匯入必要的模組。同樣,匯入 cloneElement 以對基本的 React 元素進行修改。現在,我們將使用 JSX 建立一個基本的 React 元素。此元素是一個簡單的 <div>,包含文字內容“This is a basic React element.”。然後定義 App 函式式元件。在這個元件中,我們將定義一個專案陣列。我們將使用 cloneElement 建立 basicElement 的修改版本。修改包括新增一個段落 (<p>) 和一個無序列表 (<ul>),該列表包含透過遍歷 items 陣列生成的列表項。

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;

輸出

list of items

當我們在 React 應用中使用此元件時,它將呈現修改後的元素,顯示一個段落和一個無序專案列表。

示例 - 讓我們建立一個使用 cloneElement 的應用程式

在這個應用中,我們將建立一個簡單的 React 應用,它使用 cloneElement 來突出顯示專案列表中的特定專案。該應用包含兩個元件:List 元件和 Row 元件,以及一個父級 App 元件,用於顯示產品列表。

  • List 元件 - 它接收一個子元件列表。維護 selectedIndex 狀態以跟蹤當前突出顯示的專案。使用 Children.map 迭代子項,並使用 cloneElement 根據 selectedIndex 修改 isHighlighted prop。

  • Row 元件 - 它將產品標題渲染為一行。如果 isHighlighted prop 為 true,則應用 CSS 類進行突出顯示。

  • data.js 模組 - 它定義了一個產品物件的陣列。

  • App.js - 在這個檔案中,我們將匯入 List 和 Row 元件以及產品資料。並使用 List 元件呈現產品列表。

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>
   );
}

輸出

cloneElement

總結

因此,cloneElement 是 React 中一個有用的函式,它通常被使用,但也可能會給我們的程式增加複雜性和問題。瞭解何時使用 cloneElement 以及何時在我們的 React 應用中使用其他技術,可以幫助我們編寫更簡潔、更高效的程式碼。

reactjs_reference_api.htm
廣告