2015-04-02 13 views
7

come illustrato nell'esempio seguente, vorrei che MyComponent allegasse dinamicamente un evento "onClick" ai propri figli. L'evento onClick deve attivare alertView che dovrebbe essere in grado di chiamare il metodo dell'elemento su cui si fa clic "getValue".React.js: allegare evento dal genitore ai figli

JSFiddle: http://jsfiddle.net/2g638bp8/

Come fare questo? Grazie

var MyComponent = React.createClass({ 
    alertValue: function() { 
     // RETRIEVE THE CHILD HERE 
     alert(child.getValue()); 
    }, 
    render: function() { 
     var children = React.Children.map(this.props.children, function (c, index) { 
      return React.addons.cloneWithProps(c, { 
       ref: 'child-' + index 
      }); 
     }); 
     return (
      <div> 
       {children} 
      </div> 
     ); 
    } 
}); 

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

React.render(
    <div> 
     <MyComponent> 
      <MySubComponent val="1" /> 
      <MySubComponent val="2" /> 
      <MySubComponent val="3" /> 
     </MyComponent> 
    </div>, 
    document.getElementById('container') 
); 

risposta

8

Non è possibile chiamare i metodi sui componenti figlio in React. È possibile impostare solo le proprietà. (Lo child è in realtà un ReactElement che contiene informazioni sulla classe e le proprietà associate. Non è un'istanza del componente che è stato creato).

Quindi, si potrebbe pensare a questo un modo slightly different e spostare il onClick al MySubComponent:

var MyComponent = React.createClass({ 
    onHandleGiveValue: function (value) { 
     alert(value); 
    }, 
    render: function() { 
     var self  = this, 
      children = React.Children.map(this.props.children, function (c, index) { 
      return React.addons.cloneWithProps(c, {      
       onGiveValue: self.onHandleGiveValue.bind(self) 
      }); 
     }); 
     return (
      <div> 
       {children} 
      </div> 
     ); 
    } 
}); 

var MySubComponent = React.createClass({ 
    handleClick: function() { 
     this.props.onGiveValue(this.props.val); 
    }, 
    getValue: function() { 
     return this.props.val; 
    }, 
    render: function() { 
     return (
      <div onClick={ this.handleClick } >{this.props.val}</div> 
     ); 
    } 
}); 

React.render(
    <div> 
     <MyComponent> 
      <MySubComponent val="1" /> 
      <MySubComponent val="2" /> 
      <MySubComponent val="3" /> 
     </MyComponent> 
    </div>, 
    document.getElementById('container') 
); 

Facendo questo, il codice può passare il valore corrente come un evento per il componente principale. Ho creato un nuovo evento dalla classe MySubComponent denominata onGiveValue. Questo per ora passa semplicemente il valore da this.props.val. Ma potrebbe naturalmente essere qualsiasi cosa.

+0

Grazie per questa risposta utile - è ora vale la pena l'aggiornamento e il vostro violino per utilizzare 'React.cloneElement' invece ..? (a causa del fatto che 'cloneWithProps' è deprecato) –

1
  1. Passare il callback genitore al subComponent, non è necessario un riferimento per il componente figlio.
  2. React preferisce il modello di progettazione della composizione, quindi il componente padre dovrebbe contenere quei tre componenti secondari. JS Fiddle: http://jsfiddle.net/68vt3umg/

    var MyComponent = React.createClass({ 
    handleChildClick: function (e, childValue) { 
        alert(childValue); 
    }, 
    render: function() { 
        return (
         <div> 
          <MySubComponent val="1" onSubClicked={this.handleChildClick}/> 
          <MySubComponent val="2" onSubClicked={this.handleChildClick}/> 
         </div> 
        ); 
    }}); 
    
    var MySubComponent = React.createClass({ 
        getValue: function() { 
        return this.props.val; 
        }, 
        handleOnClick: function (e, value) { 
        this.props.onSubClicked(e, this.props.val); 
        }, 
        render: function() { 
        return (
         <div onClick={this.handleOnClick}>{this.props.val}</div> 
        ); 
        } 
    }); 
    
    React.render(
        <div> 
        <MyComponent /> 
        </div>, 
        document.getElementById('container') 
    ); 
    
+2

Come è diverso dalla mia risposta? – WiredPrairie

+1

Non ci sono figli passati a 'MyComponent', che è ciò che l'OP voleva –

Problemi correlati