2016-11-05 3 views
0

Ich habe seit ein paar Tagen gesucht und kann nicht scheinen, um dies zu arbeiten, und es macht mich verrückt!Ändern Sie einen Child-Status von Eltern "One Hit"

Das Ziel ist ein Akkordeon mit dem Zusatz eines "Alle erweitern"/"Alle reduzieren" -Buttons. Ich habe es geschafft, dies an einem Punkt durch Übergabe einer expandAll -Eigenschaft an die untergeordnete Komponente durch Requisiten und Aktualisieren des expand-Status des untergeordneten Elements in componentWillReceiveProps zu erreichen, aber wenn die übergeordnete Komponente so eingestellt ist, dass sie Daten automatisch für einen Timer abruft bedeutete, dass der Child-Status aktualisiert wurde, um alle Panels nach dem zweiten Abruf zu reduzieren oder zu erweitern, was nicht das erforderliche Verhalten ist.

class App extends React.Component { 

    constructor(props){ 
    super(props); 
    this.state = { 
     "teams": [{ Name: "Liverpool", Players: ["Lovren", "Coutinho"]}, {Name:"Arsenal", Players: ["Ozil", "Welbeck"]},{Name: "Chelsea", Players: []}], 
     toggleAll: false, 
     toggleText: "Expand All" 
    } 
    } 

    _toggleAll(event){ 
    event.preventDefault(); 
    let text = "Expand All"; 
    if (!this.state.toggleAll === true){ 
     text = "Collapse All" 
    } 
    this.setState({toggleAll: !this.state.toggleAll, toggleText: text}); 
    console.log("toggleAll", this.state.toggleAll); 
    } 


    render() { 
    return (
     <div className="headers"> 
     <button onClick={this._toggleAll.bind(this)}>{this.state.toggleText}</button> 
     {this.state.teams.map((team, index) => 
             <Header className="" key={index} title={team.Name} players={team.Players} /> 
     )} 

     </div> 
    ); 
    } 
} 

class Header extends React.Component { 
    constructor(props){ 
    super(props); 
    this.state = { 
     expanded: false 
    } 
    } 

    componentWillMount(){ 
    console.log(this.props.title); 
    console.log(this.props.players); 
    } 

    _expand(event){ 
    event.preventDefault(); 
    this.setState({expanded: !this.state.expanded}); 
    } 

    render() { 
    let players; 
    if(this.state.expanded) 
    { 
     players= <ul> 
        {this.props.players.map((player, index) => <li key={index}>{player}</li>)} 
       </ul> 
    } 

    return (
     <div> 

     <div className="header" > 
      <p onClick={this._expand.bind(this)}>{this.props.title}</p> 

     </div> 
     {players} 
     </div> 

    ); 
    } 
} 


React.ReactDOM.render(
    <App />, 
    document.getElementById('container') 
); 

Fiddle unter bereitgestellt https://jsfiddle.net/aamirjaffer/x52bhdq6/

+0

Ihre Header-Komponente sollte nicht "Status" haben. Verwenden Sie stattdessen Requisiten. –

Antwort

0

Sie brauchen eine Stütze aus dem App-Komponente passieren den Header es ist „CollapseAll“ Zustand zu geben. Ich mag so die Darstellung des Headers in App aktualisiert:

<Header 
    className = "" 
    key={index} 
    title={team.Name} 
    players = {team.Players} 
    allExpanded={this.state.toggleAll} 
/> 

Dann wird der Header-Komponente für diese Stütze Änderung auf conponentWillReceiveProps hören muss und seinen eigenen Zustand entsprechend wie so gesetzt:

componentWillReceiveProps(nextProps) { 
    if (nextProps.allExpanded !== this.props.allExpanded) { 
    this.setState({ expanded: nextProps.allExpanded }); 
    } 
} 

ich gegabelt Deine Geige gemacht, diese Änderungen und alles funktioniert ganz gut: https://jsfiddle.net/xkp4snmx/

+0

Dies ist genau das, was ich gesucht habe, ich habe das ursprünglich gemacht, aber ich habe die Prüfung nicht gemacht, bevor ich den Zustand eingestellt habe, also das Verhalten, das ich gesehen habe. Prost Ben –

+0

Awesome Aamir :-) –

0

Sie könnten kollabierten Zustand jedes Teams speichern.

this.state = { 
    teams: [ 
    { 
    Name: "Liverpool", 
    Players: ["Lovren", "Coutinho"], 
    collapsed: true 
    }, 
    { 
    Name: "Arsenal", 
    Players: ["Ozil", "Welbeck"], 
    collapsed: true 
    }, 
    { 
    Name: "Chelsea", 
    Players: ["Hazard", "Oscar", "Willian"], 
    collapsed: true 
    } 
    ] 
} 

js fidds

ps: Ich würde wahrscheinlich unabhängig von der Spielerliste machen, und es nur über CSS verstecken - weniger Berechnung und mit CSS können Sie es ordentlich Animationen für ein echtes Akkordeon Gefühl.

pss: wollen Sie es in Ihren Abstand werfen & Einrückung machte es so viel schwerer zu lesen Sie Ihren Code = |