Реагировать — переключать только одну кнопку, а не все

#reactjs

#язык JavaScript #реагирует на #словарь #onclick #тумблер

Вопрос:

У меня есть приложение, которое отображает города из API, и под каждым городом должна быть кнопка для отображения описания этого города. Теперь, когда я нажимаю на одну кнопку, все кнопки изменяют текст и отображают компонент описания.

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

 class CitiesList extends React.Component {  constructor(props) {  super(props);  this.state = {  opened: false,  }  this.toggleButton = this.toggleButton.bind(this);  };   toggleButton() {  const {opened} = this.state;  this.setState({  opened: !opened,  })  }    render() {   const items = this.props.cities.map((data, index) =gt; (  lt;div key={index}gt;  lt;h2gt;{data.city}lt;/h2gt;  lt;pgt;PM 2.5 value: {data.value} {data.unit}lt;/pgt;  {this.state.opened ? lt;Button variant="outlined" color="primary" size="small" onClick={this.toggleButton}gt;Hide city descriptionlt;/Buttongt; : lt;Button variant="outlined" color="primary" size="small" onClick={this.toggleButton}gt;Show city descriptionlt;/Buttongt;}  {this.state.opened amp;amp; lt;CityDescription/gt;}   lt;/divgt;  ));  return (  lt;divgt;  lt;divgt;  {items}  lt;/divgt;  lt;/divgt;  )  } }  

В компоненте CityDescription теперь у меня есть только:

 class CityDescription extends React.Component {   render() {  return (  lt;divgt;  description  lt;/divgt;  )  } }  

Заранее благодарю вас за вашу помощь.

Комментарии:

1. вы устанавливаете флаг true/false для отображения/скрытия описания, поэтому ваше государство не знает, какое описание показывать. Что вы можете сделать, так это установить индекс отображаемого города в штате. Например, если необходимо отобразить описание города № 2, установите значение showIndex равным 2 в штате, тогда вы можете отобразить описание условно.

Ответ №1:

Как упоминал @Muhammad, вы можете выполнить эту работу, сделав всего несколько изменений.

Приведенный ниже код должен работать:

 class CitiesList extends React.Component {  constructor(props) {  super(props);  this.state = {  opened: false,  }  };   toggleButton = (index) =gt; {  const {opened} = this.state;  this.setState({  opened: {  ...opened,  [index]: !opened[index]  }  })  }    render() {  const { opened } = this.state;  const items = this.props.cities.map((data, index) =gt; (  lt;div key={index}gt;  lt;h2gt;{data.city}lt;/h2gt;  lt;pgt;PM 2.5 value: {data.value} {data.unit}lt;/pgt;  {opened[index] ? lt;Button variant="outlined" color="primary" size="small" onClick={() =gt; this.toggleButton(index)}gt;Hide city descriptionlt;/Buttongt; : lt;Button variant="outlined" color="primary" size="small" onClick={() =gt; this.toggleButton(index)}gt;Show city descriptionlt;/Buttongt;}  {opened[index] amp;amp; lt;CityDescription/gt;}   lt;/divgt;  ));  return (  lt;divgt;  lt;divgt;  {items}  lt;/divgt;  lt;/divgt;  )  } }  

Ответ №2:

Вам понадобится opened штат для каждого города. Вы можете сделать это, сохранив массив объектов, и каждый объект будет содержать вот так {id: lt;it can be indexgt;, opened: lt;true/falsegt;} .

Ответ №3:

Решение Раби джа работает, но всего несколько минут назад я сделал это по-другому.

В CitiesList я оставил только

 const items = this.props.cities.map((data, index) =gt; (  lt;div key={index}gt;  lt;h2gt;{data.city}lt;/h2gt;  lt;pgt;PM 2.5 value: {data.value} {data.unit}lt;/pgt;  lt;CityDescription/gt;  lt;/divgt;  ));  

а остальное я перешел на CityDescription компонент, и это тоже работает.