### Overriding props of an element {/*overriding-props-of-an-element*/}
To override the props of some <CodeStepstep={1}>React element</CodeStep>, pass it to `cloneElement` with the <CodeStepstep={2}>props you want to override</CodeStep>:
Here, the resulting <CodeStepstep={3}>cloned element</CodeStep> will be `<Row title="Cabbage" isHighlighted={true} />`.
**Let's walk through an example to see when it's useful.**
Imagine a `List` component that renders its [`children`](/learn/passing-props-to-a-component#passing-jsx-as-children) as a list of selectable rows with a "Next" button that changes which row is selected. The `List` component needs to render the selected `Row` differently, so it clones every `<Row>` child that it has received, and adds an extra `isHighlighted: true` or `isHighlighted: false` prop:
export default function Row({ title, isHighlighted }) {
return (
<divclassName={[
'Row',
isHighlighted ? 'RowHighlighted' : ''
].join(' ')}>
{title}
</div>
);
}
```
```js data.js
export const products = [
{ title: 'Cabbage', id: 1 },
{ title: 'Garlic', id: 2 },
{ title: 'Apple', id: 3 },
];
```
```css
.List {
display: flex;
flex-direction: column;
border: 2px solid grey;
padding: 5px;
}
.Row {
border: 2px dashed black;
padding: 5px;
margin: 5px;
}
.RowHighlighted {
background: #ffa;
}
button {
height: 40px;
font-size: 20px;
}
```
</Sandpack>
To summarize, the `List` cloned the `<Row />` elements it received and added an extra prop to them.
<Pitfall>
Cloning children makes it hard to tell how the data flows through your app. Try one of the [alternatives.](#alternatives)
</Pitfall>
---
## Alternatives {/*alternatives*/}
### Passing data with a render prop {/*passing-data-with-a-render-prop*/}
Instead of using `cloneElement`, consider accepting a *render prop* like `renderItem`. Here, `List` receives `renderItem` as a prop. `List` calls `renderItem` for every item and passes `isHighlighted` as an argument:
```js {1,7}
export default function List({ items, renderItem }) {
The `renderItem` prop is called a "render prop" because it's a prop that specifies how to render something. For example, you can pass a `renderItem` implementation that renders a `<Row>` with the given `isHighlighted` value:
```js {3,7}
<List
items={products}
renderItem={(product, isHighlighted) =>
<Row
key={product.id}
title={product.title}
isHighlighted={isHighlighted}
/>
}
/>
```
The end result is the same as with `cloneElement`:
```js {4,8,12}
<List>
<Row
title="Cabbage"
isHighlighted={true}
/>
<Row
title="Garlic"
isHighlighted={false}
/>
<Row
title="Apple"
isHighlighted={false}
/>
</List>
```
However, you can clearly trace where the `isHighlighted` value is coming from.
<Sandpack>
```js
import List from './List.js';
import Row from './Row.js';
import { products } from './data.js';
export default function App() {
return (
<List
items={products}
renderItem={(product, isHighlighted) =>
<Row
key={product.id}
title={product.title}
isHighlighted={isHighlighted}
/>
}
/>
);
}
```
```js List.js active
import { useState } from 'react';
export default function List({ items, renderItem }) {
[Learn more about passing data through context.](/apis/react/useContext#passing-data-deeply-into-the-tree)
---
### Extracting logic into a custom Hook {/*extracting-logic-into-a-custom-hook*/}
Another approach you can try is to extract the "non-visual" logic into your own Hook, and use the information returned by your Hook to decide what to render. For example, you could write a `useList` custom Hook like this:
* `element`: The `element` argument must be a valid React element. For example, it could be a JSX node like `<Something />`, the result of calling [`createElement`](/apis/react/createElement), or the result of another `cloneElement` call.
* `props`: The `props` argument must either be an object or `null`. If you pass `null`, the cloned element will retain all of the original `element.props`. Otherwise, for every prop in the `props` object, the returned element will "prefer" the value from `props` over the value from `element.props`. The rest of the props will be filled from the original `element.props`. If you pass `props.key` or `props.ref`, they will replace the original ones.
* **optional**`...children`: Zero or more child nodes. They can be any React nodes, including React elements, strings, numbers, [portals](/apis/react-dom/createPortal), empty nodes (`null`, `undefined`, `true`, and `false`), and arrays of React nodes. If you don't pass any `...children` arguments, the original `element.props.children` will be preserved.
#### Returns {/*returns*/}
`cloneElement` returns a React element object with a few properties:
* `type`: Same as `element.type`.
* `props`: The result of shallowly merging `element.props` with the overriding `props` you have passed.
* `ref`: The original `element.ref`, unless it was overridden by `props.ref`.
* `key`: The original `element.key`, unless it was overridden by `props.key`.
Usually, you'll return the element from your component or make it a child of another element. Although you may read the element's properties, it's best to treat every element as opaque after it's created, and only render it.
#### Caveats {/*caveats*/}
* Cloning an element **does not modify the original element.**
* You should only **pass children as multiple arguments to `createElement` if they are all statically known,** like `cloneElement(element, null, child1, child2, child3)`. If your children are dynamic, pass the entire array as the third argument: `cloneElement(element, null, listItems)`. This ensures that React will [warn you about missing `key`s](/learn/rendering-lists#keeping-list-items-in-order-with-key) for any dynamic lists. For static lists this is not necessary because they never reorder.
* `cloneElement` makes it harder to trace the data flow, so **try the [alternatives](/#alternatives) instead.**