Изменение состояния изображения на основе индекса массива — React.js

#javascript #reactjs #loops #dom

#javascript #reactjs #циклы #dom

Вопрос:

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

Я думаю, что состояние не должно изменяться в цикле for, и мне интересно, может ли проблема быть в {this.state.arrowShown amp;amp; } . Поэтому, как я могу изменить только состояние svg карты, на которую нажимают, не изменяя состояние других?

 import Container from 'react-bootstrap/Container'
import Card from 'react-bootstrap/Card'
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import { withTranslation } from 'react-i18next';
import Accordion from 'react-bootstrap/Accordion'
import Button from 'react-bootstrap/Button'

class ProjectCard extends React.Component {

    constructor() {
        super();
        this.state = {
            arrowShown: true,
            arrowHidden: false,
        }
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick(event, index) {
        const id = event.currentTarget.id;
        const projectArr = this.props.projects;
        console.log("this.props.porjects", this.props.projects)
        for (var i = 0; i < projectArr.length; i  ) {
            console.log("projectArr[i].idP1", projectArr[i].idP2)
            if (projectArr[i].idP2 === id) {
                console.log("same same")
                this.setState({
                    arrowShown: !this.state.arrowShown,
                    arrowHidden: !this.state.arrowHidden
                })
                // newState[projectArr[i].idP2.arrowShown] = projectArr[i].idP2 === projectArr[i].idP2
            }
        }
        //     // this.setState(newState)
        // }
    }
    render() {
        const { t } = this.props;
        // arrowHidden = {}
        return (
            <React.Fragment>
                <Container fluid className=" pb-5" id="Projects">
                    <Row className="d-flex justify-content-center py-5" xs={1} md={1} lg={3}>
                        {this.props.projects.map((project, index) => (
                            <Col className="d-flex justify-content-center px-5 py-5" key= 
                               {project.keyP}>
                                <Card className="bg-warning" border="light" >
                                    <Card.Img variant="top" src={project.srcP} 
                                    className="overlay" />
                                    <Card.Body className="bg-light">
                                        <Card.Title className="text-warning" > 
                                        t(project.titleP)}</Card.Title>
                                        <Card.Text>
                                            {t(project.descriptionP)}
                                        </Card.Text>
                                        <Accordion>

                                            <Accordion.Toggle as={Button} variant="link" 
                                               eventKey="0" className="p-0" id={project.idP1}  >
                                                <Card.Title className="text-warning" >
                                                    Features

                                                 {this.state.arrowShown
                                                        <svg id={project.idP2} onClick={(event) => { this.handleClick(event, index) }} width="1em" height="1em" viewBox="0 0 16 16" className=" down bi bi-chevron-double-down" fill="currentColor" xmlns="http://www.w3.org/2000/svg" >
                                                            <path fillRule="evenodd" d="M1.646 6.646a.5.5 0 0 1 .708 0L8 12.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z" />
                                                            <path fillRule="evenodd" d="M1.646 2.646a.5.5 0 0 1 .708 0L8 8.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z" />
                                                        </svg>

                                                    }
                                                    {this.state.arrowHidden amp;amp;


                                                        <svg id={project.idP3} onClick={(event) => { this.handleClick(event, index) }} width="1em" height="1em" viewBox="0 0 16 16" className=" up bi bi-chevron-double-up" fill="currentColor" xmlns="http://www.w3.org/2000/svg"  >
                                                            <path fillRule="evenodd" d="M7.646 2.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 3.707 2.354 9.354a.5.5 0 1 1-.708-.708l6-6z" />
                                                            <path fillRule="evenodd" d="M7.646 6.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 7.707l-5.646 5.647a.5.5 0 0 1-.708-.708l6-6z" />
                                                        </svg>
                                                    }
                                                </Card.Title>
                                            </Accordion.Toggle> ```

ps: it is my first question so every feedback is welcome! Thank you for your support.

[enter image description here][1]


  [1]: https://i.stack.imgur.com/0YD01.png
  

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

1. У вас есть массив карточек, но только одно состояние стрелки (на самом деле два, но одно избыточно; «показано» совпадает с «не скрыто»). Вам нужен массив «показанных» состояний.

Ответ №1:

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

 
this.setState({
        arrowShown: !this.state.arrowShown,
        arrowHidden: !this.state.arrowHidden
    })

  

и отображение каждого изображения с одинаковым значением состояния. вот почему все изображения переворачиваются каждый раз, когда вы переворачиваете одно.

Что вы можете сделать, так это поддерживать состояние примерно так

 
       this.state = {  
           [index1] : { arrowShown : true , arrowHidden :false }  ,
           [index2] : { arrowShown : true , arrowHidden :false }  ,
       //and so on
       }

  

затем всякий раз, когда на основе индекса выбранного изображения вы обновляете состояние только для этого конкретного индекса следующим образом…

 
       this.setState({[indexOfTheClickedImage ] : { 
                arrowShown: !this.state.[indexOfTheClickedImage].arrowShown ,
                arrowHidden: !this.state.[indexOfTheClickedImage].arrowHidden
       }}

  

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

1. ПРИВЕТ, Мохаммад, большое спасибо за отличный вклад. Теперь он работает 🙂