Reputation: 15
<button className="readlink" onClick={this.moreToggle}>Read {this.state.expanded ? 'Less' : 'More'}...</button>
moreToggle = () => {
if(this.state.isExpanded == 'ansText'){
this.setState({isExpanded: 'ansText ansTextExpanded'});
this.setState({expanded: true});
}
else{
this.setState({isExpanded: 'ansText'});
this.setState({expanded: false});
}
}
I have this function moreToggle which needs to be called only for the specific div where user clicks. There are more than 1 div like this but using the above approach all div are toggled. How can this be achieved.
<div className="quesData ansData">
<div className="quesText">Does weighted blanket helps to reduce stress?</div>
<div className="askedDate">Asked on January 14, 2020</div>
<div className={this.state.isExpanded}>
Weighted blankets Weighted blankets Weighted blankets Weighted blankets Weighted blankets
Weighted blankets Weighted blankets Weighted blankets Weighted blankets Weighted blankets
Weighted blankets Weighted blankets Weighted blankets Weighted blankets Weighted blankets
Weighted blankets Weighted blankets Weighted blankets Weighted blankets Weighted blankets
Weighted blankets Weighted blankets Weighted blankets Weighted blankets Weighted blankets
Weighted blankets Weighted blankets Weighted blankets Weighted blankets Weighted blankets
Weighted blankets Weighted blankets Weighted blankets Weighted blankets Weighted blankets
Weighted blankets Weighted blankets Weighted blankets Weighted blankets Weighted blankets
Weighted blankets Weighted blankets Weighted blankets Weighted blankets Weighted blankets
</div>
<button className="readlink" onClick={this.moreToggle}>Read {this.state.expanded ? 'Less' : 'More'}...</button>
</div>
The button is used to expand the div by adding class to the content div i.e. weighted blankets div.
Upvotes: 1
Views: 227
Reputation: 760
If you have an array of object(from api), then you can add another property to each item for expanding:
import React, { useState } from "react";
export default function App() {
// for example array of object received from api
const [state,setState]=useState([{id:1,title:"first"},{id:2,title:"second"}]);
const moreToggle=(id)=>{
let result=state.find(item=>item.id===id);
// add isExpanded property to each item of array or change it
// now each item of array is like this: {id:1,title:"first", isExpanded:true or false}
result.isExpanded=!result.isExpanded;
setState([...state]);
}
return (
<div>
{state.map(item=>
<div>
<div className={item.isExpanded ? "show":"hidden"}>your {item.title} div</div>
<button onClick={()=> moreToggle(item.id)}>Read {item.isExpanded ? 'Less' : 'More'}...</button>
</div>
)}
</div>
);
}
Upvotes: 0
Reputation: 663
Try this, I have added name
attribute to each clickable and in click handle I have passed the sytheticEvent
which will give us the clicked elements name back.
import React, { useCallback, useState } from "react";
import "./styles.css";
export default function App() {
const [myState, setMyState] = useState({});
const moreToggle = useCallback((e) => {
const name = e.currentTarget.name;
console.log(name);
setMyState(prevState => ({
...prevState,
[name]: !prevState[name],
}))
}, []);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<button className="readlink" name="btn1" onClick={moreToggle}>
Read {myState.btn1 ? "Less" : "More"}...
</button>
<button className="readlink" name="btn2" onClick={moreToggle}>
Read {myState.btn2 ? "Less" : "More"}...
</button>
</div>
);
}
Upvotes: 0
Reputation: 1401
You can assign each <div>
an id like "div-1"
, in this case I use an enum: collapsibleFields.FIELD_1
and passed to the moreToggle
function and change our state to key-value pairs.
state = {
expanded: {},
isExpanded: {},
};
const collapsibleFields = {
FIELD_1 = 'FIELD_1',
FIELD_2 = 'FIELD_2',
// etc
}
<button className="readlink" onClick={() => this.moreToggle(collapsibleFields.FIELD_1)}>Read {this.state.expanded[collapsibleFields.FIELD_1] ? 'Less' : 'More'}...</button>
<div className="quesText">Does weighted blanket helps to reduce stress?</div>
<div className="askedDate">Asked on January 14, 2020</div>
<div className={this.state.isExpanded[collapsibleFields.FIELD_1]}>
moreToggle = (id) => {
this.setState({
expanded[id]: this.state.isExpanded[id] === 'ansText'
});
}
Upvotes: 1