Reputation: 351
I would like to add some props to my component using {React.cloneElement(<MyComponent />, { onClick: () => console.log('click'), style: {background: 'red'} })}
Full code:
const MyComponent = () => {
return (
<div>
foooo
</div>
);
};
....
return React.cloneElement(<MyComponent />, { onClick: () => console.log('click'), style: {background: 'red'} })
But props
are not passed into my component.
When I use:
return React.cloneElement(<div>foooo</div>, { onClick: () => console.log('click'), style: {background: 'red'} })
Props are working. Why? I don`t understand why.
Upvotes: 3
Views: 10920
Reputation: 53914
Why would you use cloneElement
when you got JSX available (can conclude it from MyComponents
syntax).
Instead do:
<MyComponent
onClick={() => console.log("click")}
style={{ background: "red" }}
/>
And fix your component:
const MyComponent = ({ style, onClick }) => {
return <div onClick={onClick} style={style}>foooo</div>;
}
JSX is sugar syntax for createElement
/ cloneElement
.
React.cloneElement(
element,
[props],
[...children]
)
React.cloneElement() is almost equivalent to:
<element.type {...element.props} {...props}>{children}</element.type>
Therefore the right syntax:
const onClick = () => console.log('click');
const style = {background: 'red'};
// Exatcly the same effect as <MyComponent .../> above
React.cloneElement(<MyComponent/>, {onClick, style}, null);
Upvotes: 4
Reputation: 2551
You need to apply props inside you component:
export const Test = (props: any) => {
return (<button {...props}>Click Me</button>);
}
In this case you can set props using
React.cloneElement(<MyComponent/>, props, null);
but I do not recommend cloning (it is too heavy) I think that it is better to use special render function in props:
export const Wrapper = (props: {render: (props: any) => any}) => {
const childProps = {style: {background: 'red'}, onClick: () => { console.log('click'); }};
if (props.render){
return props.render(childProps);
} else {
return <></>;
}
}
// ...
// usage:
export default function App() {
return (
<div className="App">
<Wrapper render={(props)=>{
return <button {...props}>TEST</button>;
}}/>
</div>
);
}
Upvotes: 4