Reputation: 45
I'm learning React, JS and I'm trying to use the .map method to display some data in an array. For each element in the array I create a button to show/hide a description with css and I'm looking for a way to only show the description of one element instead of all descriptions. It is probably unclear but here is the code :
import "./styles.css";
import React, { useState } from "react";
export default function App() {
const [showDescription, setshowDescription] = useState(false);
const [anArray] = useState([
{ title: "First Div", description: "First description"},
{ title: "Antoher Div", description: "Another description"}
]);
return (
<div className="App">
{anArray.map((val, index) => {
return (
<div className="div" key={index}>
<div className="title">{val.title}</div>
<button className="btn" onClick={() => setshowDescription(!showDescription)}>
Show description
</button>
<div id={showDescription ? "display" : "hidden"}>
<div className="description">{val.description}</div>
</div>
</div>
);
})}
</div>
);
}
Do you have any idea please ?
Upvotes: 3
Views: 85
Reputation: 7156
You can use index
to show/hide your div
. The issue is you are using only one Boolean value to handle it.
export default function App() {
const [showDescriptionIndex, setshowDescriptionIndex] = useState(-1);
const [anArray] = useState([
{ title: "First Div", description: "First description"},
{ title: "Antoher Div", description: "Another description"}
]);
return (
<div className="App">
{anArray.map((val, index) => {
return (
<div className="div" key={index}>
<div className="title">{val.title}</div>
<button className="btn" onClick={() => setshowDescriptionIndex(index)}>
Show description
</button>
<div id={showDescriptionIndex === index ? "display" : "hidden"}>
<div className="description">{val.description}</div>
</div>
</div>
);
})}
</div>
);
}
Upvotes: 3
Reputation: 202648
You've a single boolean showDescription
state that is toggling every description.
Store an index of the description you want to toggle. Use the index to match the currently mapped element. Conditionally render the description
export default function App() {
const [showId, setShowId] = useState(null);
// curried function to toggle to new index or back to null to hide
const toggleDescription = id => () => setShowId(showId => showId === id ? null : id);
const [anArray] = useState([
{ title: "First Div", description: "First description"},
{ title: "Antoher Div", description: "Another description"}
]);
return (
<div className="App">
{anArray.map((val, index) => {
return (
<div className="div" key={index}>
<div className="title">{val.title}</div>
<button className="btn" onClick={toggleDescription(index)}> // <-- pass index
Show description
</button>
{showId === index && ( // <-- check for index match
<div>
<div className="description">{val.description}</div>
</div>
)}
</div>
);
})}
</div>
);
}
Upvotes: 3
Reputation: 565
Try It
import "./styles.css";
import React, { useState } from "react";
export default function App() {
const [showDescription, setshowDescription] = useState({});
const [anArray] = useState([
{ title: "First Div", description: "First description"},
{ title: "Antoher Div", description: "Another description"}
]);
return (
<div className="App">
{anArray.map((val, index) => {
return (
<div className="div" key={index}>
<div className="title">{val.title}</div>
<button className="btn" onClick={() => setshowDescription({...showDescription, [index]: !showDescription[index]})}>
Show description
</button>
<div id={showDescription && showDescription[index] ? "display" : "hidden"}>
{showDescription[index]}
<div className="description">{val.description}</div>
</div>
</div>
);
})}
</div>
);
}
Tip: Use class="show/hide"
instead of id="show/hide"
Upvotes: 2