React: React.cloneElement(this.props.children, this.props) copies the children into the this.props.children of children itself

Created on 10 Sep 2016  路  4Comments  路  Source: facebook/react

https://jsfiddle.net/69z2wepo/55774/

please run the js fiddle given above. cloneElement copies the children into props.children of the child itself

and if the child also renders its children using the same method - an infinite loop is established and the browser maximum call stack size is exceeded.

Ideally, while cloning the children property of the props of the child should be left untouched.

Wontfix

Most helpful comment

I understand, but this is a very specific use case, and rather than bake it into React, I think it should be solved in userland. There are plenty of use cases where you _want_ children to be passed so we will default to a less opinionated way, and it鈥檚 up to you to opt out and clarify what you meant with code.

For example, with spread operator:

const { children, ...otherProps } = this.props;
const newChild = React.cloneElement(children, otherProps);

Without object spread:

const { children } = this.props;

const otherProps = Object.assign({}, this.props);
delete otherProps.children;

const newChild = React.cloneElement(children, otherProps);

All 4 comments

This looks like correct behavior. children is part of props. If you pass this.props as second argument to cloneElement, children will be there. I don鈥檛 see why you鈥檇 expect them to be treated differently in this case, since children prop is not treated differently in any other cases.

Maybe we can provide a toggle or blacklist of props that we do not want to merge in such scenarios.

Here is my scenario. I am building an application using react, redux, and react-redux.
I have mapped my state values and action dispatch methods to props in my root component.

I have nested components in my application thanks to react-router. In order to pass state and dispatch methods as props to children i use

{ React.cloneElement(this.props.children, this.props) }

Now the issue is that when i use the same statement in a child to further pass down the pass state and dispatch methods as props - It renders itself which in turn again renders itself and so on - kicking in an infinite loop.

I understand, but this is a very specific use case, and rather than bake it into React, I think it should be solved in userland. There are plenty of use cases where you _want_ children to be passed so we will default to a less opinionated way, and it鈥檚 up to you to opt out and clarify what you meant with code.

For example, with spread operator:

const { children, ...otherProps } = this.props;
const newChild = React.cloneElement(children, otherProps);

Without object spread:

const { children } = this.props;

const otherProps = Object.assign({}, this.props);
delete otherProps.children;

const newChild = React.cloneElement(children, otherProps);

Sounds good to me. I agree with that my suggestion is opinionated based on my case. Thanks

Was this page helpful?
0 / 5 - 0 ratings