softwareUser
softwareUser

Reputation: 448

Show and hide looped elements in ReactJs

I loop through an array of elements:

this.props.connections.map((connection) => (

For each element in this array a card is created. In this card, I implemented a toogle button:

<div id="bookmarkIcon">
    {this.state.available ? (
    <Tab onClick={this.handleChange} icon={<StarBorderIcon/>}
        aria-label="StarBorder"/>) : <Tab onClick={this.handleChange} icon={<StarIcon/>}
                                                     aria-label="StarIcon"/>}
  </div>

The handle change method changes the value of available to false. The problem is that then I change the state and therefore, ever icon toggles, but I just want to toggle the icon I clicked on. How can I achieve this?

Upvotes: 2

Views: 2828

Answers (3)

Mahydul Islam Shajal
Mahydul Islam Shajal

Reputation: 232

Class-Based Component

class PrivacyPolicyDetails extends Component {
    constructor(props) {
        super(props);
        this.state ={
            resultData:[],
            error:false ,
            active: false,
            activeIdList:[]
        }
        this.toggleClass.bind(this);
    }
    componentDidMount() {
        setting.getQuestionAnswerByType('privacy-policy')
        .then(res =>{
              if(res.data.questionAnswerList.length > 0){
                this.setState({
                    resultData: res.data.questionAnswerList,
                  })
              }else{
                  this.setState({
                    error:true
                  });
              }
            
          }
          );
    }
    toggleClass(id) {
        const currentState = this.state.active;
        this.setState({ active: !currentState});
        if(this.state.activeIdList.find(element => element == id)){
            this.state.activeIdList = this.state.activeIdList.filter(item => item !== id);
        }else{
            this.state.activeIdList.push(id);
        }
      }
    
    render() {
        const { product, currency } = this.props;
        const {resultData,error,activeIdList} = this.state;
        
        return (
            <div>
                <h1>Privacy Policy</h1>
                {resultData && resultData.length > 0 ? resultData.map(each_policy =>
                    <div className="item">
                    <div className="question"
                      onClick={() => this.toggleClass(each_policy.question_answer_repository_id)}
                    >
                      {each_policy.question}
                    </div>
                    <p className={(activeIdList.find(element => element == each_policy.question_answer_repository_id))? "active-div" :"hide"}>
                        <div className="answer">{each_policy.answer}</div>
                    </p>
                  </div>
                ):''}
            </div>
        );
    }
}
const mapStateToProps = (state) => {
    return state.setting;
};
export default connect(mapStateToProps)(PrivacyPolicyDetails);

css

.hide{
    display: none;
    overflow:hidden;
}
.active-div{
    display: block;
    overflow:hidden;   
}

Upvotes: 1

Salmin Skenderovic
Salmin Skenderovic

Reputation: 1720

You can create an object which keeps the state as keys. Here is a working example:

hidden will look something like this {0: true, 1: true, 2: false} so we can update the corresponding items by their index.

https://codesandbox.io/s/intelligent-black-83cqg?file=/src/App.js:0-577

import React, { useState } from "react";
import "./styles.css";

export default function App() {
  const [hidden, setHidden] = useState({});

  const list = ["aa", "bb", "cc", "dd"];

  const toggleHide = index => {
    setHidden({ ...hidden, [index]: !hidden[index] });
  };

  return (
    <div className="App">
      {list.map((item, index) => (
        <div>
          {!!hidden[index] && <span>[HIDDEN]</span>}
          {!hidden[index] && <span>[VISIBLE]</span>}
          {item} <span onClick={e => toggleHide(index)}>x</span>
        </div>
      ))}
    </div>
  );
}

Upvotes: 2

Taylor Burke
Taylor Burke

Reputation: 444

Make the card into its own component and implement the state of the toggle inside of that component. In your parent component just map each card into one of these components. Each card will have its own toggle which uses the state of the card to determine how it should display.

Upvotes: 0

Related Questions