Reputation: 448
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
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
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
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