Как фильтровать(), используя значения из состояния?

#javascript #reactjs

#javascript #reactjs

Вопрос:

У меня есть список спортивных залов в моем районе:

 gyms = [
  {
    "name": "The Gym",
    "equipment": ["nothing"]
  },
  {
    "name": "24 Fitness",
    "equipment": ["kettlebell","barbell"]
  },
  {
    "name": "Gym studio",
    "equipment": ["jump rope","barbell","dumbbell"]
  },
]
  

У меня также есть класс, в штате которого есть оборудование, необходимое мне для моей следующей тренировки. Кроме того, когда я нажимаю кнопку, я бы хотел, чтобы handleClick() отфильтровывал тренажерные залы, в которых есть необходимое мне оборудование. Вот что у меня есть на данный момент:

 class App extends React.Component {
  constructor() {
    super()
    this.state = {
      neededEquipment: ["barbell","jump rope"],
      gym: ""
    }
    this.handleClick = this.handleClick.bind(this)
  }

  handleClick() {
    this.setState({
      gym: Gyms.filter(gym => (
          gym.equipment.every(e => this.state.neededEquipment.has(e))
      ))
    })
  }

  render() {
    return(
      <div>
        <p>{this.state.gym}</p>
        <button onClick={this.handleClick}>Press</button>
      </div>
    )
  }
}
  

Пока кнопка ничего не отображает на экране, и я бы хотел [в этом примере] показать «Gym studio».
Я полностью зациклен на том, как заставить handleClick() работать должным образом.
Любая помощь очень ценится.

Ответ №1:

Вам нужно пойти другим путем: при фильтрации убедитесь, что .every необходимое оборудование в состоянии включено в equipment массив тренажерного зала:

 gym: Gyms.filter(gym => (
  this.state.neededEquipment.every(
    equip => gym.equipment.includes(equip)
  )
))
  

Также обратите внимание, что .has это метод для наборов, например new Set(['foo', 'bar']) — чтобы проверить, что массив содержит значение, используйте .includes вместо этого. (Здесь у вас есть только массивы, так что используйте .includes )

Вы также, вероятно, захотите правильно отобразить доступные тренажерные залы, возможно, путем сопоставления с их именами. Заменить

 <p>{this.state.gym}</p>
  

с чем-то вроде

 <p>
  {this.state.gym.map(gym => <div>{gym.name}</div>)}
</p>
  

(или путем упорядочивания каждого тренажерного зала, или путем перечисления как названия тренажерного зала, так и его доступного оборудования, или чего-то еще)