Jakaria Ridoy
Jakaria Ridoy

Reputation: 142

Bootstrap 4 collapse not working with map in ReactJS

I am trying to add collapse to a project where it will display all the available content when Read More button (which is working for collapsing button) got clicked. But, it only collapsing for the first item that fetched from the database, and for every other Read More button click it is not working for that particular item rather it keeps opening and closing the first item. Below is my code that I am trying with. I need help with this issue. Thanks very much.

<div>
  <div className="container mt-3">
    <h1 className="text-justify mb-4">The Blogstar Blog</h1>
    <div>
      {data && data.length > 0 ? (
        data.map((item, index) => {
          return (
            <div className="card p-3 mt-3" key={index}>
              <div className="d-flex">
                <div className="text-justify mr-5">
                  <h3>{item.title}</h3>
                </div>
                <div className="d-flex ml-auto ">
                  <p className="mt-2 mr-2">
                    <img
                      src="https://img.icons8.com/material-rounded/18/000000/facebook-like.png"
                      alt="facebook-like-icon"
                    />{' '}
                    {item.upvotes}
                  </p>
                  <p className="mt-2 mr-2">
                    <img
                      src="https://img.icons8.com/material-rounded/18/000000/thumbs-down.png"
                      alt="thumbs-down-icon"
                    />{' '}
                    {item.downvotes}
                  </p>
                  <p className="mt-2">
                    <img
                      src="https://img.icons8.com/ios-filled/18/000000/comments.png"
                      alt="comments-icon"
                    />{' '}
                    {item.comments}
                  </p>
                </div>
              </div>
              <div className="d-flex">
                <p>
                  <img
                    src="https://img.icons8.com/ios-glyphs/18/000000/clock.png"
                    alt="clock-icon"
                  />
                  {formatDate(item.createdAt)}{' '}
                </p>
                <p>
                  <img
                    className="ml-2"
                    src="https://img.icons8.com/material-rounded/18/000000/writer-male.png"
                    alt="author-icon"
                  />{' '}
                  <strong>{item.author.name}</strong>
                </p>
              </div>
              <div className="text-justify">
                {ReactHtmlParser(item.content.substring(0, 150))}
                <button
                  class="btn btn-primary"
                  type="button"
                  data-toggle="collapse"
                  data-target="#collapseExample"
                  aria-expanded="false"
                  aria-controls="collapseExample">
                  Read More
                </button>
                <div class="collapse" id="collapseExample">
                  {ReactHtmlParser(item.content)}
                </div>
              </div>
            </div>
          );
        })
      ) : (
        <div>Nothing in database</div>
      )}
    </div>
  </div>
</div>

Video Reference Of How My Working Code Behaving

Upvotes: 0

Views: 703

Answers (1)

bas
bas

Reputation: 15722

Change the data-target on your collapse button to this:

data-target={`#collapseExample${index}`}

and your collapse div to this:

<div class="collapse" id={`collapseExample${index}`}>
   // ... content
</div>

The problem was that your collapse id and button data-target were static. These values need to be dynamic depending on the data you're mapping through. Otherwise your button will always target the same element. This explains why every button collapses/expands the same div.

Upvotes: 2

Related Questions