Skip to content

Instantly share code, notes, and snippets.

@dandelany
Last active March 27, 2024 10:06
Show Gist options
  • Star 35 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save dandelany/1ff06f4fa1f8d6f89c5e to your computer and use it in GitHub Desktop.
Save dandelany/1ff06f4fa1f8d6f89c5e to your computer and use it in GitHub Desktop.
Recursively cloning React children
var RecursiveChildComponent = React.createClass({
render() {
return <div>
{this.recursiveCloneChildren(this.props.children)}
</div>
},
recursiveCloneChildren(children) {
return React.Children.map(children, child => {
if(!_.isObject(child)) return child;
var childProps = {someNew: "propToAdd"};
childProps.children = this.recursiveCloneChildren(child.props.children);
return React.cloneElement(child, childProps);
})
}
})
@adamgravita
Copy link

Fantastic, was working on an issue like this for a while!

@nucab
Copy link

nucab commented Jun 27, 2018

recursiveCloneChildren(children) {
  return React.Children.map(children, (child) => {
    if (!React.isValidElement(child)) return child;
    const props = { ...{ className: '' }, ...child.props };
    let childProps = {};
    if (React.isValidElement(child) && !props.className.includes('exclude-node')) {
      childProps = {
        show: this.state.show,
        toggle: this.toggle,
      };
    }
    childProps.children = this.recursiveCloneChildren(child.props.children);
    return React.cloneElement(child, childProps);
  });
}

if you have SVG icon beneath your elements. this could be helpful.

@kurtisdunn
Copy link

This helped me to no end. Legends the lot of you!

@pavel-lens
Copy link

pavel-lens commented Nov 22, 2019

Recursive cloning React children in Typescript

Use case: A form has a global Enable/Disable switch which should make all the elements in the form disabled.

function recursiveCloneChildren(children: React.ReactElement[], newProps: any) {
  return React.Children.map(children, (child: React.ReactElement) => {
    if (!React.isValidElement(child)) {
      return child
    }
    
    // Eg. String has no props
    if (child.props) {
      // @ts-ignore
      childProps.children = recursiveCloneChildren(child.props.children, newProps);
      return React.cloneElement(child, newProps);
    }
    return child;
  });
}

In usage you need to change type.

render() {
  ...
  { recursiveCloneChildren(children as React.ReactElement[], { disabled: true }) }
   ...
}

@leonidkuznetsov18
Copy link

Recursive cloning React children in Typescript

Use case: A form has a global Enable/Disable switch which should make all the elements in the form disabled.

function recursiveCloneChildren(children: React.ReactElement[], newProps: any) {
  return React.Children.map(children, (child: React.ReactElement) => {
    if (!React.isValidElement(child)) {
      return child
    }
    
    // Eg. String has no props
    if (child.props) {
      // @ts-ignore
      childProps.children = recursiveCloneChildren(child.props.children, newProps);
      return React.cloneElement(child, newProps);
    }
    return child;
  });
}

In usage you need to change type.

render() {
  ...
  { recursiveCloneChildren(children as React.ReactElement[], { disabled: true }) }
   ...
}

childProps????? maybe newProps !!!

@matthew-dean
Copy link

What if a child component has no children, but returns a tree, and you want to recursively clone / modify the returned tree?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment