2015-12-25 12 views
6

Ho due tipi di componenti. Chiamiamoli esterni e interni. Immaginate qualcosa di simile:Come verificare quanti bambini React hanno un determinato sostegno?

<Outer> 
    <h4>{this.prop.title} ({this.state.withX}/{this.state.total})</h4> 
    <Inner isX/> 
    <Inner isX/> 
    <Inner/> 
    <Inner/> 
</Outer> 

Ho questa funzione:

getInitialState: function() { 
    return { 
     total: React.Children.count(this.props.children), 
     withX: /// ??? /// 
    }; 
} 

Come posso ottenere quel valore? Stavo cercando di ottenere qualcosa del genere:

withX: function() { 
    var counter = React.Children.forEach(this.props.children, function(child) { 
     // if... 
     return //something 
    }); 
return counter; 
} 

Ma ... sento che otterrà me da nessuna parte.

risposta

6

Quando si esegue l'iterazione sui bambini, è possibile ispezionare i propri oggetti di scena. Ad esempio, utilizzando il metodo forEach avete sopra, si potrebbe fare qualcosa di simile:

withX: function() { 
    var counter = 0; 
    React.Children.forEach(this.props.children, function(child) { 
    if (child.props.isX) counter++; 
    }); 
    return counter; 
} 

Reagire fornisce anche un toArray helper che ti permette di fare la stessa cosa usando le belle metodi di array JS fornisce:

return React.Children.toArray(this.props.children).filter(function(child) { 
    return child.props.isX; 
}).length; 

Se stai usando ES6, può fare questo molto brevemente con una funzione di freccia:

return React.Children.toArray(this.props.children).filter(c => c.props.isX).length; 

L'unico problema è che, se Outer sta eseguendo il conteggio, quindi anche Outer deve eseguire il rendering di h4. Ecco un esempio completo:

const App = React.createClass({ 
    render() { 
    return (
     <Outer title="Things"> 
     <Inner isX/> 
     <Inner isX/> 
     <Inner/> 
     <Inner/> 
     </Outer> 
    ); 
    } 
}); 

const Outer = React.createClass({ 
    getInitialState() { 
    return { 
     total: React.Children.count(this.props.children), 
     withX: this.countChildrenWithX(this.props.children) 
    }; 
    }, 

    countChildrenWithX(children) { 
    const { toArray } = React.Children; 
    return toArray(children).filter(c => c.props.isX).length; 
    }, 

    render() { 
    return (
     <div> 
     <h4>{this.props.title} ({this.state.withX}/{this.state.total})</h4> 
     <hr /> 
     {this.props.children} 
     </div> 
    ); 
    } 
}); 

const Inner = React.createClass({ 
    render() { 
    return <div>Inner - withX = {String(!!this.props.isX)}</div>; 
    } 
}); 

E here's a working JS Bin di dimostrare: https://jsbin.com/xameyun/edit?js,output

+0

Hah! Questa è un'ottima risposta. Grazie, molto istruttivo. Sono felice di vedere che stavo pensando in una direzione corretta. Sono molto felice che tu abbia mostrato vari modi per ottenere la stessa cosa. La sintassi ES6 è semplicemente perfetta. –

Problemi correlati