Reputation: 276
I was playing around with React and I have a list of elements like this:
{posts.map((post) => (
<div className ="hidden" key={post.key}></div>
<button onClick = {() => showMore()}>Click to Show</button>
))}
posts is a list of json objects. The idea is that only a short description of the post would show and when the button is clicked, it shows the full body.
posts = [{
"title": "Title",
"description": "",
"thumbnail": 'images/image.png',
"body": "",
"id": 1
}]
I want to show that particular post when the button for it is clicked. This is easy to do with document.getElementById but I'm unable to do this with React.
The only way I can think of is a single useState for all the posts but this is not what I want.
This is different from just showing or hiding a single element because in this case I can't just create a single useState. I guess I could create as many useStates as there are posts but I don't really know how this would work.
Thanks!
Upvotes: 0
Views: 71
Reputation: 1908
The way I would approach this is by creating a Post component which has an internal state:
const Post = ({ post }) => {
const [showMore, setShowMore] = useState(false);
const handleShowMore = () => setShowMore((prevShowMore) => !prevShowMore);
return (
<div class="post" key={post.id}>
<p>{showMore ? post.description : post.description.substring(0, 10)}</p>
<button onClick={handleShowMore}>
Show {showMore ? "Less" : "More"}
</button>
</div>
);
};
If showMore
is false (which it is by default), it will only show the first 10 characters of the string. If it is true, it will show the entire string.
Then in your parent component, I'd map over the posts and render the Post component:
const ParentComponent = () => {
return (
<div className="container">
{data.map((post) => (
<Post post={post} />
))}
</div>
);
};
Here is a example: https://codepen.io/AliKlein/pen/KKajvOW
Is this close to what you're trying to accomplish?
Upvotes: 2