2015-01-07 14 views
10

Ho un componente generico che mappa i suoi componenti figlio per filtrare solo i bambini di un certo tipo, come trovato di seguito.Confronto di due componenti - è Componente X un'istanza del Componente A

Tuttavia, l'utilizzo della proprietà type era una semplice ipotesi e non riesco a trovarlo documentato. Non solo, la registrazione mostra che si tratta di una funzione, che non può essere eseguita. Oltre a questo c'è un paio di problemi che devono essere risolti quando si utilizza Browserify.

Un'altra opzione potrebbe essere quella di leggere child.prototype.displayName. Ma anche questo sembra sbagliato.

Domanda: Fondamentalmente, sto cercando un modo solido per confrontare se due componenti ReactJS sono uguali.

ESEMPIO

(Aggiornato: non così male, dopo tutto)

var Foo = React.createClass({ 
    render: function() { 
     return <div>Foo</div>; 
    } 
}); 

var Bar = React.createClass({ 
    render: function() { 
     return <div>Bar</div>; 
    } 
}); 

var Main = React.createClass({ 
    render: function() { 
     var filteredChildren = []; 

     filteredChildren = React.Children.map(function(child) { 
      if (child.type === Foo.type) { 
       return child; 
      } 
     }); 

     return (
      <div> 
       {filteredChildren} 
      </div> 
     ); 
    } 
}); 

React.render(<Main><Foo /><Bar /></Main>, document.body); 
+0

In che senso vuoi conoscere i componenti sono uguali? Equivale significa che rendono lo stesso risultato? –

+1

No, possono essere (e sono) totalmente diversi. Devo sapere se sono un'istanza dello stesso React.createClass(). – David

+1

Correlati: https://www.bountysource.com/issues/3127455-proptypes-define-children-component-type – David

risposta

12

Credo che il vostro esempio sia corretta.

Infatti, in React 0.12 child.type === Foo.type è l'unico confronto che funziona.
Questo è relativo a React 0.12 in corso di deprecating wrapper functions.

Quando 0.13 è spento, child.type sarà Foo.

Nitpick: non utilizzare this.props.children.map, this won't work when there is less than two children.
Utilizzare invece React.Children.map.

+0

Grazie per aver fatto luce! Questo spiega perché 'child.type' sembra essere una funzione. Per quanto riguarda il pignolo, hai perfettamente ragione, e in effetti dovresti usare React.Children.map! – David

+2

Sebbene non specificamente pertinente a questo esempio di domande, se si creano classi ES6 anziché utilizzare React.createClass, è possibile utilizzare l'istanza di: 'child.type.prototype instanceof Foo' - L'ho scoperto in [la mia domanda simile] (http://stackoverflow.com/questions/35584279/looping-this-props-children-how-do-i-test-their-type?stw=2) – mjohnsonengr

2

Il tipo di API che stai creando è fragile e confuso. Non dovresti trattare gli elementi come dati. Se è necessario filtrare, passare i dati al componente.

<Main things={[ 
    {type: 'Foo', element: <Foo />}, 
    {type: 'Bar', element: <Bar />}, 
    {type: 'Bar', element: <div>I'm lying but it doesn't matter</div>}, 
]} /> 
var Main = React.createClass({ 
    render: function(){ 
     var filteredChildren = this.props.things.map(function(thing){ 
      return thing.type === 'Foo' ? thing.element : false; 
     }); 

     return <div>{filteredChildren}</div>; 
    } 
}); 
+1

Il più delle volte questo è vero. Ci sono casi rari quando il confronto è legittimo. Ad esempio, se il componente esporta anche sottocomponenti e desidera applicare un trattamento speciale per tipi specifici, ad es. '

alcuni'. –

+1

E perché dovresti sapere in cosa si tratta? Menu.Item esegue il rendering di una voce di menu e Menu.Separator esegue il rendering di un separatore. E Menu dovrebbe solo rendere le sue cose e (condizionatamente) includere questo. – FakeRainBrigand

+0

Avevo un caso d'uso in cui volevo racchiudere ognuno dei 'figli' passati in un' div', eccetto i separatori. Anche se hai ragione, con 'Menu.Articolo "Non avrei davvero bisogno di questo controllo - ero troppo pigro per avvolgere ogni oggetto. –

Problemi correlati