2016-08-21 3 views
5

Скажем, у меня есть компонент Parent, который отображает набор компонентов Child. При зависании одного из этих компонентов Child я хочу выделить (bg color) компоненты Child, которые принадлежат к одной группе.Как выбрать группу детей из родителя?

См ниже код, каждый Child имеет свойство группы:

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

Если я парить Child с идентификатором собственности 6, как я выделяю все Child компонентов, которые в той же группы, то есть группы 2?

NB: Я новичок в реактиве и сожалею, если заголовок вводит в заблуждение.

ответ

3

Я бы подошел к этому с локальным состоянием:

В двух словах мы генерируем переменную состояния для текущей группы родителя. Затем мы даем каждому ребенку прокси-метод, который он вызывает на onMouseEnter, где он передает свой group prop родительскому методу. Затем каждый рендер сравнивает активную группу с ее собственной группой и устанавливает активную опору на ребенка. Затем ребенок проверяет свою активную опору, чтобы применить класс active. Очевидно, вы можете значительно расширить это поведение. Проверьте Систему Реагирования событий, here.

Эта скрипка очень зачаточном пример того, как это работает:

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

это здорово. Не могли бы вы объяснить мне, как работает этот код?'className = {this.props.active && 'active'}' – Matthew

+2

Конечно! Это довольно «короткое замыкание» оценки для присвоения имени класса. Поскольку 'active' - это булевская форма, переданная компоненту, мы можем оценить ее. Если он будет «истинным», он продолжит оценку и назначит строку 'active' (в данном случае, наше имя класса). В случае, если это «ложь», он остановится и вообще не назначит класс). Я видел эту схему в React, когда вы либо хотите присвоить что-то или вообще ничего (в отличие от тернарного оператора). Надеюсь, это прояснит! –

+0

В качестве дополнения вы можете написать его так: 'className = {this.props.active? 'active': ''} '. Оба подхода эквивалентны. Мне просто нравится, как лучше. –

3

Ну, это может быть сделано с помощью простого кода css + некоторые изменения. Во-первых, если у вас мало групп, которые означают списки групп, что означает список списков. У вас будет компонент Container, компонент Group и компонент GroupItem. Контейнер отобразит несколько компонентов Группы, которые будут отображать несколько компонентов GroupItem.

Было бы что-то вроде этого:

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

теперь дают каждой группе класс, который при наведении будет выделить сыновей:

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

теперь, когда вы наведете группу, которая как наведение одного элемента, но применительно ко всем предметам, все его дети будут подсвечены.

+0

Спасибо. Я упростил реальный случай; на самом деле я даже не пользуюсь списками, а css сетками. Добавление компонента группы между ними делает вещи сложными в моем случае. есть ли другой возможный вариант? – Matthew

+0

Можете ли вы предоставить свой код до сих пор? – Pachu

+0

Сейчас будет сложно скомпилировать код. Дело в том, что я хочу, чтобы сетка css была как можно более простой. Ваше решение является лучшим, если это применимо, поэтому я поддержал. Принял Марио, потому что он просто подходит для моего конкретного случая. Спасибо! – Matthew

Смежные вопросы