2017-02-27 2 views
0

Ich habe Daten mit Eltern und Kindern und möchte dies als Tabelle rendern. Wenn Sie auf einen Elternteil klicken, sollten die Kinder zusammenklappen.React - Tabelle onClick einklappen

Ich versuchte dies, indem ich Kindern einen Klassennamen von Eltern gab. Wenn Sie also auf das Elternelement klicken, werden alle Klassen mit demselben Namen ausgewählt. Ich habe gelesen, dass Sie in React die Änderungen im DOM nicht vornehmen sollten. Als ob es schon nicht schwer genug wäre!

Hier ist mein Tisch. (Während es war, bin Rendering ich ein neues tbody pro Elternteil, da schreit Reagieren über die richtige Rückkehr Elemente reagieren .. Ich würde wirklich, wie es nur alle s sein, wenn möglich)

render() { 
     return (
      <table> 
       <thead> 
       <tr> 
        <th>Name</th> 
        <th>value</th> 
       </tr> 
       </thead> 
       {this.props.data.items.map(function (parent) { 
        return (
         <tbody> 
         <tr> 
          <td >{parent.name}</td> 
         </tr> 
         {parent.children.map(function (child) { 
          return (
           <tr> 
            <td>{child.name}</td> 
            <td>{child.value}</td> 
           </tr> 
          ) 
         })} 
         </tbody> 
        ) 
       })} 
      </table> 
     ) 
    } 
} 

Daten wie folgt aussehen diese

[{ 
    "name": "Food", "children": [ 
    {"name": "Apple", "value": 5.6}, 
    {"name": "Banana", "value": 2.2}, 
    {"name": "Peer", "value": 1.6}, 
    ] 
}, 
{ 
    "name": "Drink", "children": [ 
    {"name": "Cola", "value": 5.6}, 
    {"name": "Juice", "value": 2.2}, 
    {"name": "Water", "value": 1.6}, 
    ] 
} 
] 

Antwort

0

Sie benötigen einen onClick Event-Handler auf dem übergeordneten td <td><button value={parent.name} onClick={this.handleClick}>{parent.name}</button></td>

Dann benötigen Sie eine Methode handle in Ihrer Komponente, die eine Redux Aktion ausgelöst und aktualisiert den Zustand. Sie benötigen eine neue Eigenschaft in Ihrer Datenstruktur, um zu speichern, ob das übergeordnete Element geöffnet oder geschlossen ist. So etwas wie [{"name": "Food", "children": [...], "open": true}].

Jetzt können Sie in der übergeordneten für die Eigenschaft überprüfen und nur die auf dem Bool {parent.open ? parent.children.map(...) : ''}

Endergebnis ähnliche

handleClick(event) { 
    this.props.toggleParent(event.target.value); 
} 
render() { 
     return (
      <table> 
       <thead> 
       <tr> 
        <th>Name</th> 
        <th>value</th> 
       </tr> 
       </thead> 
       {this.props.data.items.map(function (parent) { 
        return (
         <tbody> 
         <tr> 
          <td><button value={parent.name} onClick={this.handleClick}>{parent.name}</button></td> 
         </tr> 
         {parent.open ? parent.children.map(function (child) { 
          return (
           <tr> 
            <td>{child.name}</td> 
            <td>{child.value}</td> 
           </tr> 
          ) 
         }.bind(this) : ''} 
         </tbody> 
        ) 
       })} 
      </table> 
     ) 
    } 
+0

Dank etwas spirift aussehen würde, basierend Kinder zeigen! Ich mag diese Antwort, aber ich habe 1 Problem. Ich habe die Funktion in einer Elternkomponente und übergibt sie als Prop. Wenn Sie jetzt auf Folgendes klicken: onClick = {() => {this.props.handleClick (event)}}. Es sagt mir, dass dies nicht definiert ist. – Macdows

+1

Schwer zu wissen, ohne den Code zu sehen, aber ich denke, dass Sie das onClick 'onClick = {this.props.handleClick}' Ereignis verwenden können, wird automatisch als erstes Argument übergeben. Vielleicht benötigen Sie die anonyme Pfeilfunktion, aber das würde geschrieben werden als: 'onClick = {(event) => this.props.handleClick (event)}' – spirift

+0

Dies wurde behoben, indem() => im Parent und nicht im Child verwendet wurde . Ich habe auch Pfeilfunktionen in beiden Kartenfunktionen verwendet, oder ich hätte beide binden müssen, anstatt nur die 1, die du getan hast. Vielen Dank! – Macdows