I\'m trying to find the proper way to define some components which could be used in a generic way:
You can use React.Children to iterate over the children, and then clone each element with new props (shallow merged) using React.cloneElement. For example:
const Child = ({ doSomething, value }) => (
);
class Parent extends React.Component{
doSomething = value => {
console.log("doSomething called by child with value:", value);
}
render() {
const childrenWithProps = React.Children.map(this.props.children, child => {
// checking isValidElement is the safe way and avoids a typescript error too
const props = { doSomething };
if (React.isValidElement(child)) {
return React.cloneElement(child, props);
}
return child;
});
return {childrenWithProps};
}
}
function App() {
return (
);
}
ReactDOM.render( , document.getElementById("container"));
Fiddle: https://jsfiddle.net/2q294y43/2/
Alternatively, you can pass props to children with render props. In this approach, the children (which can be children or any other prop name) is a function which can accept any arguments you want to pass and returns the children:
const Child = ({ doSomething, value }) => (
);
class Parent extends React.Component{
doSomething = value => {
console.log("doSomething called by child with value:", value);
}
render(){
// note that children is called as a function and we can pass args to it
return {this.props.children(doSomething)}
}
};
function App(){
return (
{doSomething => (
)}
);
}
ReactDOM.render( , document.getElementById("container"));
Instead of or simply <> you can also return an array if you prefer.
Fiddle: https://jsfiddle.net/ferahl/y5pcua68/7/