Реагировать на материал при нажатии кнопки "Свернуть" [ответ обновлен]

У меня есть компонент с некоторым списком деталей. В каждом списке в компоненте есть кнопка «Подробности». когда пользователь нажимает на кнопку. Он отобразит дополнительную информацию для списка. Здесь я использую Material-Ui с реакцией, и для этой цели я импортировал компонент Collapse. Итак, как вы видите мой код ниже, когда я нажимаю кнопку «Детали» в одном списке, он открывает детали для всего списка. Я хочу только открыть список, нажимаю. Пожалуйста, проверьте мой код ниже

Заранее спасибо.

import React, { Component } from 'react';
import Collapse from '@material-ui/core/Collapse';
import Button from '@material-ui/core/Button';


class Collapsed extends Component {
    constructor(props){
        super(props);
        this.state = {
            expanded: {},
            details: [
                {
                    id: 0,
                    name: 'Tony Stark',
                    role: 'Iron Man' 
                },
                {
                    id: 1,
                    name: 'Steve Rogers',
                    role: 'Captain America',
                },
                {
                    id: 2,
                    name: 'Thor',
                    role: 'God of Thunder'
                }
            ]
        }
    }
    handleExpandClick = (id) => {
        const expended = this.state.expended;
        expended[id] = expended.hasOwnProperty(id) ? !expended[id] : true
        this.setState({ expended });
      }
  render() {
      const { details, expanded } = this.state;
    return (
      <div>
        {details.map((detail)=>(
            <div key={detail.id}>
                {detail.name}
                <Button 
                    variant="contained"
                    disableRipple  
                    onClick={() => this.handleExpandClick(detail.id)}
                    aria-expanded={expanded}
                    aria-label="Show more"
                >
                    Details
                </Button>
                <Collapse in={expanded[detail.id]} timeout="auto" unmountOnExit>
                    {detail.role}
                </Collapse>
            </div>    
        ))}
      </div>
    )
  }
}

export default Collapsed

person Jeyanth Kanagaraj    schedule 05.04.2019    source источник
comment
Привет, ты хочешь просто открыть детали или тоже хочешь закрыть?   -  person Maxime Girou    schedule 05.04.2019
comment
Мне тоже нужно закрыть.   -  person Jeyanth Kanagaraj    schedule 05.04.2019
comment
Хорошо, я обновил свой ответ   -  person Maxime Girou    schedule 05.04.2019


Ответы (3)


Вместо использования одной переменной для хранения «израсходованного» значения как логического, вы можете использовать объект с идентификатором каждой детали.

    import React, { Component } from 'react';
import Collapse from '@material-ui/core/Collapse';
import Button from '@material-ui/core/Button';


class Collapsed extends Component {
    constructor(props){
        super(props);
        this.state = {
            expanded: {},
            details: [
                {
                    id: 0,
                    name: 'Tony Stark',
                    role: 'Iron Man' 
                },
                {
                    id: 1,
                    name: 'Steve Rogers',
                    role: 'Captain America',
                },
                {
                    id: 2,
                    name: 'Thor',
                    role: 'God of Thunder'
                }
            ]
        }
    }
    handleExpandClick = (id) => {
        this.setState({ expanded: ...this.state.expanded, [id] : true });
      };
  render() {
      const {details, expanded} = this.state;
    return (
      <div>
        {details.map((detail)=>(
            <div key={detail.id}>
                {detail.name}
                <Button 
                    variant="contained"
                    disableRipple  
                    onClick={()=>this.handleExpandClick(detail.id)}
                    aria-expanded={expanded}
                    aria-label="Show more"
                >
                    Role
                </Button>
                <Collapse in={expanded[detail.id]} timeout="auto" unmountOnExit>
                    {detail.role}
                </Collapse>
            </div>    
        ))}
      </div>
    )
  }
}

export default Collapsed

Если вы хотите иметь возможность закрыть израсходованную деталь, вы можете использовать функцию дескриптора, например:

handleExpandClick = (id) => {
  let expended = this.state.expended;
  expended = expended.hasOwnProperty(id) ? !expended[id] : true
  this.setState({ expended });
}
person Maxime Girou    schedule 05.04.2019
comment
Я получаю сообщение об ошибке Ошибка анализа: неожиданный токен в строке setState для оператора распространения - person Jeyanth Kanagaraj; 05.04.2019
comment
Вы меняете израсходованный вид в состоянии? - person Maxime Girou; 05.04.2019

Попробуй это

import React, { Component } from 'react';
import Collapse from '@material-ui/core/Collapse';
import Button from '@material-ui/core/Button';
import _ from 'lodash';

class Collapsed extends Component {
    constructor(props) {
        super(props);
        this.state = {
            details: [
                {
                    id: 0,
                    name: 'Tony Stark',
                    role: 'Iron Man'
                },
                {
                    id: 1,
                    name: 'Steve Rogers',
                    role: 'Captain America',
                },
                {
                    id: 2,
                    name: 'Thor',
                    role: 'God of Thunder'
                }
            ]
        }
    }
    handleExpandClick(id) {
        console.log(this.state[`expanded_${id}`]);
        this.setState({ [`expanded_${id}`]:  _.isUndefined(this.state[`expanded_${id}`])?true:!this.state[`expanded_${id}`] });
    };
    render() {
        const { details, expanded } = this.state;
        return (
            <div>
                {details.map((detail) => (
                    <div key={detail.id}>
                        {detail.name}
                        <Button
                            variant="contained"
                            disableRipple
                            onClick={this.handleExpandClick.bind(this,detail.id)}
                            aria-expanded={this.state[`expanded_${detail.id}`] || false}
                            aria-label="Show more"
                        >
                            Role
                </Button>
                        <Collapse in={this.state[`expanded_${detail.id}`] || false} timeout="auto" unmountOnExit>
                            {detail.role}
                        </Collapse>
                    </div>
                ))}
            </div>
        )
    }
}

export default Collapsed
person Malik Adil    schedule 05.04.2019

с крючками:

const [expanded, setExpanded] = useState({});

    const handleClick = (id) => {
    setExpanded({
      ...expanded,
      [id]: !expanded[id]
    });
  }
<Collapse in={expanded[id]} timeout="auto" unmountOnExit>
    {detail.role}
 </Collapse>
person Manuel Carmona    schedule 17.01.2020