2016-08-21 2 views
5

Angenommen, ich habe eine Parent Komponente, die einen Satz Child Komponenten rendert. Wenn ich eine dieser Child Komponente schwebe, möchte ich die Child Komponenten hervorheben (bg Farbe), die zur selben Gruppe gehören.Wie wähle ich eine Gruppe von Kindern aus dem Elternteil?

Siehe Code unten hat jede Child eine Gruppe Eigenschaft:

https://jsfiddle.net/69z2wepo/53442/

const Parent = React.createClass({ 
    render() { 
     const rows = []; 
     let group = 1; 
     for (let i = 1; i <= 12; i++) { 
      rows.push(<Child key={i} id={i} group={group} />); 

      if (i % 3 === 0) { 
       group++; 
      } 
     } 
     return (
      <ul> 
       {rows} 
      </ul> 
     ); 
    } 
}); 

const Child = React.createClass({ 
    render() { 
     return (
      <li className="child">id: {this.props.id} - group: {this.props.group}</li> 
     ); 
    } 
}); 

ReactDOM.render(
    <Parent />, 
    document.getElementById('app') 
); 

Wenn ich schweben Child mit id-Eigenschaft von 6, wie kann ich alle die Child Komponenten hervorheben, die in der sind gleiche Gruppe, dh Gruppe 2?

NB: Ich bin neu zu reagieren und tut mir leid, wenn der Titel irreführend ist.

Antwort

3

Ich würde dies mit lokalen Zustand wie folgt nähern:

Kurz gesagt, generieren wir eine Statusvariable für die aktuelle Gruppe auf dem übergeordneten Element. Dann geben wir jedem Kind eine Proxy-Methode, die es onMouseEnter aufruft, wo es seine group-Stütze an die Elternmethode übergibt. Dann wird bei jedem Rendervorgang die aktive Gruppe mit der eigenen Gruppe verglichen und die aktive Stütze auf das Kind gesetzt. Das Kind prüft dann seine aktive Stütze, um eine active Klasse anzuwenden. Offensichtlich können Sie dieses Verhalten um vieles erweitern. Schau dir das Event System von React an, here.

Diese Geige ist ein sehr rudimentäres Beispiel dafür, wie es funktioniert:

https://jsfiddle.net/69z2wepo/53444/

CSS

.active { 
    background-color: yellow; 
} 

JS

const Parent = React.createClass({ 
    getInitialState() { 
     return { 
      group: null 
     } 
    }, 

    render() { 
     const rows = []; 
     let group = 1; 

     for (let i = 1; i <= 12; i++) { 
      const child = <Child 
       key={i} 
       id={i} 
       group={group} 
       hover={(group) => this.setState({ group })} 
       active={group === this.state.group} />; 

      rows.push(child); 

      if (i % 3 === 0) { 
       group++; 
      } 
     } 

     return (
      <ul> 
       {rows} 
      </ul> 
     ); 
    } 
}); 

const Child = React.createClass({ 
    render() { 
     return (
      <li 
       className={this.props.active && 'active'} 
       onMouseEnter={() => this.props.hover(this.props.group)} 
      > 
       id: {this.props.id} - group: {this.props.group} 
      </li> 
     ); 
    } 
}); 

ReactDOM.render(
    <Parent />, 
    document.getElementById('app') 
); 
+0

das ist großartig. Könnten Sie mir bitte erklären, wie dieser Code funktioniert?'className = {this.props.active && 'active'}' – Matthew

+2

Sicher! Dies "verkettet" die Bewertung, um einen Klassennamen zuzuweisen. Da 'active' eine boolesche Requisite ist, die an die Komponente übergeben wird, können wir dagegen auswerten. Sollte es "wahr" sein, wird die Auswertung fortgesetzt und der String "aktiv" (in diesem Fall unser Klassenname) zugewiesen. Falls es "falsch" ist, wird es dort aufhören und überhaupt keine Klasse zuweisen. Ich habe dieses Muster in React oft gesehen, wenn Sie entweder etwas oder gar nichts zuweisen wollen (im Gegensatz zu einem ternären Operator). Hoffe das klärt es auf! –

+0

Als Zusatz könnte man es so schreiben: 'className = {this.props.active? 'aktiv': ''} '. Beide Ansätze sind gleichwertig. Ich mag den ersteren besser. –

3

Nun, es könnte durch einfache CSS-Code + einige reagieren Modifikationen durchgeführt werden. Erstens, wenn Sie nur wenige Gruppen haben, bedeutet das Listen von Gruppen, dh Liste von Listen. Sie hätten die Container-Komponente, die Group-Komponente und die GroupItem-Komponente. Der Container wird nur wenige Gruppenkomponenten darstellen, die nur wenige GroupItem-Komponenten darstellen.

Es wäre so etwas wie dieses:

export default class Container extends React.Component { 
    render() { 
     return(<ul> 
      {this.state.groups.map((group) => { 
       return <Group items={group.items} /> 
      })} 
     </ul>) 
    } 
} 

export default class Group extends React.Component { 
    render() { 
     return (<ul> 
      {this.props.items.map((item) => { 
       return <GroupItem /> 
      })} 
     </ul>) 
    } 
} 

export default class GroupItem extends React.Component { 
    render() { 
     return (<li>some content here</li>); 
    } 
} 

jetzt jeder Gruppe geben eine Klasse, wenn Sie die Kinder schweben wird Highlight:

.group:hover > li { 
    background-color: color; 
} 

jetzt, wenn Sie die Gruppe schweben wird, das ist, wie das Schweben eines einzelnen Elements, aber gilt für alle Elemente, alle seine Kinder werden hervorgehoben

+0

Danke. Ich habe den realen Fall sehr vereinfacht; Tatsächlich benutze ich nicht einmal Listen, sondern CSS-Grids. Das Hinzufügen einer Gruppenkomponente dazwischen macht die Sache in meinem Fall kompliziert. Gibt es eine andere mögliche Option? – Matthew

+0

Können Sie Ihren Code bisher bereitstellen? – Pachu

+0

Es wird ein bisschen schwierig, Code jetzt zu teilen. Die Sache ist, dass ich möchte, dass das CSS-Gitter so einfach wie möglich ist. Ihre Lösung ist die beste, falls zutreffend, also habe ich upvoted. Akzeptiert Mario, weil es einfach besser für meinen speziellen Fall passt. Danke! – Matthew

Verwandte Themen