Inject a child prop
A wrapper component needs to add or override a prop on a single supplied child while retaining the child's type and other props.
React 19+ · Function
Creates a new React element from an existing valid element, selectively overriding its props, key, ref, or children. The original element remains unchanged.
cloneElement creates a new React element from an existing valid element. It shallowly combines the original props with supplied overrides, preserves the original children when no child arguments are provided, and can replace the key or ref.
cloneElement(element, props, ...children)| Name | Type | Description |
|---|---|---|
element | React element | A valid React element, such as JSX, a createElement result, or another cloneElement result. |
props | object | null | An object of overriding props, or null to retain the source props. |
...children | ReactNode | Optional React child nodes. If omitted, the source element's children are preserved. |
A new React element object with the source type, shallowly merged props, and original key/ref unless overridden.
import { cloneElement, type ReactElement } from 'react';
type ButtonProps = { children: React.ReactNode; className?: string };
function Emphasize({ child }: { child: ReactElement<ButtonProps> }) {
return cloneElement(child, {
className: `${child.props.className ?? ''} emphasized`.trim(),
});
}
export default function App() {
return <Emphasize child={<button className="primary">Save</button>} />;
}The wrapper creates a new button element while preserving its existing props and replacing only the className.
A wrapper component needs to add or override a prop on a single supplied child while retaining the child's type and other props.
A component needs to replace or augment an element's children while retaining its element type and selected original props.
A controlled composition pattern requires explicitly changing an element's key or ref at the cloning boundary.
It accepts a valid React element, an object or null for props, and optional child nodes. The returned element uses the supplied prop values over the original ones and otherwise retains the original props.
Follow-up: What happens to children when none are supplied? The original element.props.children is retained; supplying child arguments replaces them.
It returns a new React element object with the same type by default. Its props are produced by shallowly merging the source props with the overriding props.
Follow-up: Does it deep-merge nested props? No. The documented merge is shallow, so nested objects require an explicitly constructed replacement value.
A valid React element can be a JSX node, the result of createElement, or the result of another cloneElement call. The source element itself is not modified.
Follow-up: When might cloneElement be a poor design choice? When it obscures data flow; explicit component props, context, or a render prop can often communicate ownership more clearly.
createElementisValidElementChildrencreateContext