2015-12-25 1 views
6

Ich habe zwei Arten von Komponenten. Nennen wir sie äußerlich und innerlich. Stellen Sie sich vor etwas wie folgt aus:Wie überprüft man wie viele React Kinder eine bestimmte Requisite haben?

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

Ich habe diese Funktion:

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

Wie bekomme ich diesen Wert? Ich habe versucht, etwas wie folgt zu bekommen:

Aber ... Ich fühle, dass es mich nirgends bekommen wird.

Antwort

6

Wenn Sie über die Kinder iterieren, können Sie ihre Requisiten überprüfen. Zum Beispiel mit der forEach Methode, die Sie oben haben, könnten Sie so etwas tun:

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

Reagieren auch ein toArray helper bieten, die Sie tun das gleiche mit der netten Array Methoden JS läßt bestimmt:

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

wenn Sie ES6 verwenden, können dies mit einem Pfeil Funktion ganz kurz und bündig tun:

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

Der einzige Haken ist, dass, wenn Outer macht das Zählen, dann Outer muss auch die h4 rendern. Hier ist ein vollständiges Beispiel:

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>; 
    } 
}); 

Und here's a working JS Bin zu demonstrieren: https://jsbin.com/xameyun/edit?js,output

+0

Hah! Das ist eine großartige Antwort. Danke, sehr informativ. Ich bin froh zu sehen, dass ich in eine richtige Richtung denke. Ich bin sehr froh, dass Sie verschiedene Möglichkeiten gezeigt haben, dasselbe zu erreichen. Die ES6-Syntax ist einfach perfekt. –

Verwandte Themen