2016-08-21 14 views
5

Powiedz, że mam komponent Parent, który renderuje zestaw komponentów Child. Po najechaniu na jeden ze składników Child, chciałbym podświetlić (kolor bg) komponenty Child należące do tej samej grupy.Jak wybrać grupę dzieci od rodzica?

patrz kod poniżej, każdy Child ma właściwość Grupa:

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

Gdybym aktywowania Child z właściwości ID 6, w jaki sposób zaznaczyć wszystkie elementy Child będących w ta sama grupa, tj. grupa 2?

NB: Jestem nowy, aby reagować i przepraszam, jeśli tytuł wprowadza w błąd.

Odpowiedz

3

Podejdę do tego z lokalnym stanem:

W skrócie, generujemy zmienną stanu dla bieżącej grupy na rodzica. Następnie dajemy każdemu dziecku metodę proxy, którą wywołuje na onMouseEnter, gdzie przekazuje ona swoją propozycję group do metody nadrzędnej. Następnie każdy render porównuje grupę aktywną z własną grupą i ustawia aktywny element pomocniczy na elemencie podrzędnym. Dziecko następnie sprawdza aktywne podłoże, aby zastosować klasę active. Oczywiście możesz znacznie przedłużyć to zachowanie. Sprawdź system zdarzeń React, here.

Ten skrzypce to bardzo prymitywny przykład jak to działa:

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

to świetnie. Czy mógłbyś mi wyjaśnić, jak działa ten kod?'className = {this.props.active && 'active'}' – Matthew

+2

Pewnie! To prawie "zwarcie" oceny, aby przypisać nazwę klasy. Ponieważ 'active' jest boolowskim podpisem przekazanym do komponentu, możemy go ocenić. Jeśli będzie "prawda", będzie kontynuował ocenę i przypisze ciąg 'active' (w tym przypadku nasza nazwa klasy). W przypadku, gdy jest to "false", zatrzyma się tam i nie będzie w ogóle przypisywał klasy). Często widziałem ten wzorzec w React, kiedy albo chcesz coś przypisać, albo nic (w przeciwieństwie do operatora trójskładnikowego). Mam nadzieję, że to oczyszcza! –

+0

Jako dodatek, możesz napisać tak jak poniżej: 'className = {this.props.active? "aktywny": ""} ". Oba podejścia są równoważne. Po prostu lubię dawniej lepiej. –

3

Cóż, Można to zrobić za pomocą prostego kodu css + trochę modyfikacji reakcji. Po pierwsze, jeśli masz kilka grup, co oznacza listy grup, co oznacza listę list. Będziesz miał komponent Container, Group component i GroupItem. Kontener wyrenderuje kilka komponentów grupy, które będą renderować kilka komponentów GroupItem.

To byłoby coś takiego:

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

teraz dać każdej grupy klasy, która po najechaniu podkreśli synów:

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

teraz kiedy będzie oscylować grupę, która jest jak najechanie na pojedynczy element, ale dotyczy wszystkich przedmiotów, wszystkie jego dzieci zostaną podświetlone.

+0

Dziękuję. Bardzo uprościłem prawdziwy przypadek; właściwie nie używam nawet list, ale siatki css. Dodanie komponentu Grupy pomiędzy sprawia, że ​​w moim przypadku sprawa jest skomplikowana. czy jest jakaś inna możliwa opcja? – Matthew

+0

Czy możesz podać swój kod do tej pory? – Pachu

+0

Teraz będzie trochę trudno udostępnić kod. Chodzi o to, że chcę, aby sieć css była tak prosta, jak to tylko możliwe. Twoje rozwiązanie jest najlepsze, jeśli dotyczy, więc przegłosowałem. Zaakceptował Mario, ponieważ lepiej pasuje do mojego konkretnego przypadku. Dzięki! – Matthew

Powiązane problemy