简体   繁体   中英

React: why doesn't React.addons.cloneWithProps work with Components?

I don't know if this is a bug or how to work this around, but I've noticed that React.addons.cloneWithProps works with standard tags (like <div> ) but not with children that are components.

This is a working example of the problem. I expect both the divs to have a red background, but the one created with a component does not.

http://jsfiddle.net/ydpk2dp7/1/

var Main = React.createClass({
    render: function() {     
       children = React.Children.map(this.props.children, function (c, index) {
            return React.addons.cloneWithProps(c, {
                style: {
                    background: 'red'
                }
            });
       });

       return (
           <div>
               {children}
           </div>
       );
    },    
});

var Comp = React.createClass({
    render: function() {     
          return (
              <div>{this.props.children}</div>
          ); 
    }
});


React.render(
    <Main>
        <div>1</div>
        <Comp>2</Comp>
    </Main>
    , document.body);

I'm not sure if this is a bug or not but I would wrap the react components in a parent not owned by the parent component. The below provides a working result.

var Main = React.createClass({
    render: function() {     
       children = React.Children.map(this.props.children, function (c, index) {
            return React.addons.cloneWithProps(c, {style: {background: 'red'}});
       });

       return (
           <div>
               {children}
           </div>
       );
    },    
});

var Comp = React.createClass({
    render: function() {     
          return (
              <div>{this.props.children}</div>
          ); 
    }
});


React.render(
    <Main>
        <div>
            <Comp>2</Comp>
            <Comp>3</Comp>
            <Comp>4</Comp>
        </div>
    </Main>
    , document.body)

Late to the party, but thought I'd help whoever sees this in the future.

The problem is you're discarding the style prop in Comp :

var Comp = React.createClass({
    render: function() {
          var style = this.props.style; // you weren't passing this to the <div> below
          return (
              <div style={style}>{this.props.children}</div>
          );
    }
});

It's probably best to extract what you need from props and pass on the rest. Easily done with ES2015's destructuring spread operator :

var Comp = React.createClass({
    render: function() {
          var { children, ...props } = this.props;
          return (
              <div {...props}>{ children }</div>
          );
    }
});

This will allow props to be specified on your component that, when initially writing, you didn't think of.

Now, for example, you can now add an onClick handler and expect it to work:

<Comp onClick={this.onClick} />

Remember , only props on "DOM" elements have special meaning. To custom elements, they're just regular properties for you to interpret as you wish.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM