element: Аргумент element должен быть действительным элементом React. Например, это может быть JSX-узел типа <Something />, результат вызова createElement или результат другого вызова cloneElement.
props: Аргумент props должен быть либо объектом, либо null. Если вы передадите null, клонированный элемент сохранит все исходные element.props. В противном случае для каждого пропса в объекте props возвращаемый элемент "предпочтет" значение из props значению из element.props. Остальные пропсы будут заполнены из исходного element.props. Если вы передадите props.key или props.ref, они заменят исходные.
опционально...children: Ноль или более дочерних узлов. Это могут быть любые узлы React, включая элементы React, строки, числа, порталы, пустые узлы (null, undefined, true и false) и массивы узлов React. Если вы не передадите никаких аргументов ...children, исходные element.props.children будут сохранены.
cloneElement возвращает объект React element с несколькими свойствами:
type: Такой же, как element.type.
props: Результат неглубокого слияния element.props с переданными вам переопределяющими props.
ref: Оригинальный element.ref, если только он не был переопределен props.ref.
key: Оригинальный element.key, если он не был переопределен props.key.
Обычно вы возвращаете элемент из своего компонента или делаете его дочерним элементом другого элемента. Хотя вы можете читать свойства элемента, лучше всего рассматривать каждый элемент как непрозрачный после его создания и только отображать его.
Клонирование элемента не изменяет исходный элемент.
Вы должны передавать дочерние элементы в качестве нескольких аргументов cloneElement, только если они все статически известны, например, cloneElement(element, null, child1, child2, child3). Если ваши дочерние элементы динамические, передайте весь массив в качестве третьего аргумента: cloneElement(element, null, listItems). Это гарантирует, что React предупредит вас об отсутствии ключей для любых динамических списков. Для статических списков это не нужно, потому что они никогда не меняют порядок.
cloneElement затрудняет отслеживание потока данных, поэтому вместо этого попробуйте альтернативы.
Здесь результирующим клонированным элементом будет <Row title="Cabbage" isHighlighted={true} />.
Давайте рассмотрим пример, чтобы увидеть, когда это полезно..
Представьте себе компонент List, который отображает своих детей как список выбираемых строк с кнопкой "Next", которая изменяет выбранную строку. Компонент List должен отображать выбранный Row по-разному, поэтому он клонирует каждый дочерний <Row>, который он получил, и добавляет дополнительный параметр isHighlighted: true или isHighlighted: false:
Вместо того чтобы использовать cloneElement, подумайте о том, чтобы принимать render prop, например renderItem. Здесь List принимает renderItem в качестве пропса. List вызывает renderItem для каждого элемента и передает isHighlighted в качестве аргумента:
Пропс renderItem называют "пропсом рендеринга", потому что он определяет, как рендерить что-либо. Например, вы можете передать реализацию renderItem, которая рендерит <Row> с заданным значением isHighlighted:
Другой подход, который вы можете попробовать - это извлечь "невизуальную" логику в свой собственный хук, и использовать информацию, возвращаемую вашим хуком, чтобы решить, что отображать. Например, вы можете написать пользовательский хук useList следующим образом: