Попытка использовать реакцию для запуска разных компонентов с одной и той же функцией

Я пытаюсь сделать аккордеон с помощью React, но получаю данные из Json API, который динамически использую для создания таблицы. Все это работает. Однако, когда я пытаюсь использовать функцию toggleHidden, она открывает каждое отдельное представление вместо того, на которое я только что нажал. Как я могу настроить таргетинг на конкретный компонент при нажатии вместо простого использования это

<Table striped bordered condensed hover>
  <thead>
    <tr>
      <th>Asset #</th>
      <th>Description</th>
      <th>Person</th>
      <th>Username</th>
      <th>Room</th>
      <th>ID</th>
      <th>Patches</th>
      <th>Date</th>
      <th>Java</th>
      <th>AACV</th>
    </tr>
   </thead>

   {this.state.items.map((data, key) => {
     return (
       <tbody>
         <tr 
           id = {data.name} 
           onClick=`{this.toggleHidden.bind(this)} 
         >`
           <td>{data.name}</td>
           <td >{data.height}</td>
           <td>{data.mass}</td>
           <td>{data.gender}</td>
           <td >{data.birth_year}</td>
           <td>{data.eye_color}</td>
           <td >{data.birth_year}</td>
           <td>{data.eye_color}</td>
           <td >{data.birth_year}</td>
           <td>{data.eye_color}</td>
         </tr>
         <td 
           className = {data.name} 
           colSpan = "10"
         > 
          {!this.state.isHidden && <Filled/>}
         </td>
       </tbody>
     )
   })}
 </Table>



 toggleHidden (e) {
    this.setState({
        isHidden: !this.state.isHidden
    })
}

У вас есть <td/> вне <tr/>. Может, захочешь это исправить.

Ted 23.04.2018 21:43

Это портит формат, и это выходит за рамки моих непосредственных проблем.

NEMS05 23.04.2018 21:47

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

Ted 23.04.2018 21:58
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
3
31
2

Ответы 2

Ну, вам нужно сделать вложенное состояние для каждого ключа, что означает

const { Table, Icon } = semanticUIReact;

const ITEMS = [
  {
    asset: "Asset 1",
    description: "Description"
  },
  {
    asset: "Asset 2",
    description: "Description2"
  }
];
class Example extends React.Component {
  constructor(props) {
    super(props);

    this.state = { items: ITEMS };
    this.renderRow = this.renderRow.bind(this);
  }

  render() {
    return (
      <Table striped bordered condensed selectable>
        <Table.Header>
          <Table.Row>
            <Table.HeaderCell>Asset</Table.HeaderCell>
            <Table.HeaderCell>Description</Table.HeaderCell>
          </Table.Row>
        </Table.Header>

        <Table.Body>{this.state.items.map(this.renderRow)}</Table.Body>
      </Table>
    );
  }

  renderRow(data, key) {
    return (
      <Table.Row onClick = {() => this.toggleHidden(key)}>
        <Table.Cell>{data.asset}</Table.Cell>
        <Table.Cell textAlign = "right">
          {this.state[key] ? "This is hidden" : data.description}
        </Table.Cell>
      </Table.Row>
    );
  }

  toggleHidden(key) {
    this.setState({
      [key]: !this.state[key]
    });
  }
}

ReactDOM.render(<Example />, document.getElementById("react"));
<link href = "https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.1/semantic.min.css" rel = "stylesheet" />

<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src = "https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/semantic-ui-react.min.js"></script>

<div id = "react"></div>

Я получаю TypeError: невозможно прочитать свойство isHidden из undefined

NEMS05 23.04.2018 21:51

@ NEMS05 Я добавил полный рабочий фрагмент (пожалуйста, запустите в полном режиме)

Milos Mosovsky 23.04.2018 22:17

Я бы посоветовал вам использовать мощь компонентов. Создайте компонент для строки внутри таблицы, примерно так:

export default class Row extends React.Component {

 render() {
   const { data } = this.props;
         <tbody>
         <tr 
           id = {data.name} 
           onClick=`{this.toggleHidden.bind(this)} 
         >`
           <td>{data.name}</td>
           <td >{data.height}</td>
           <td>{data.mass}</td>
           <td>{data.gender}</td>
           <td >{data.birth_year}</td>
           <td>{data.eye_color}</td>
           <td >{data.birth_year}</td>
           <td>{data.eye_color}</td>
           <td >{data.birth_year}</td>
           <td>{data.eye_color}</td>
         </tr>
         <td 
           className = {data.name} 
           colSpan = "10"
         > 
          {!this.state.isHidden && <Filled/>}
         </td>
       </tbody>
 }
 toggleHidden() {
  this.setState(state => ({
    isHidden: !state.isHidden 
}));
}
}

и в вашем основном компоненте сделайте что-то вроде этого:

<Table striped bordered condensed hover>
  <thead>
    <tr>
      <th>Asset #</th>
      <th>Description</th>
      <th>Person</th>
      <th>Username</th>
      <th>Room</th>
      <th>ID</th>
      <th>Patches</th>
      <th>Date</th>
      <th>Java</th>
      <th>AACV</th>
    </tr>
   </thead>

   {this.state.items.map((data, key) => <Row data = {data} />}
 </Table>

он более читабелен, в нем больше стиль реагирования, и он позволяет каждой строке обрабатывать свое собственное состояние

(может быть какая-то синтаксическая ошибка, но концепция работает)

Удачи!

Другие вопросы по теме