Abubakar Oluyinka
Abubakar Oluyinka

Reputation: 351

Make a button expand and collapse in map function in ReactJS

I am working on a project as a means to practice some stuff in react and I need to render a button for each of the map data. I did this successfully but expand and collapse has been giving me issue. Whenever I click on the button all data collapse and expand together.

const DataFetch = () => {
 ...
  const [btnValue, setBtnValue] = useState('+');

  const handleChange = (e) => {
    setShowData(!showData);
    setBtnValue(btnValue === '+' ? '-' : '+');
  };

  return (
    <div className='container'>
      ...
      {studentResults
        .filter((val) => {
          if (searchTerm === '') {
            return val;
          } else if (
            val.firstName.toLowerCase().includes(searchTerm.toLowerCase()) ||
            val.lastName.toLowerCase().includes(searchTerm.toLowerCase())
          ) {
            return val;
          } else {
            return null;
          }
        })
        .map((student) => {
          return (
            <div key={student.id}>
              <div className='card'>
                <div className='row'>
                  <div className='col-2'>
                    <div className='pic'>
                      <img src={student.pic} alt='avatar' />
                    </div>
                  </div>
                  <div className='col'>
                    <div className='details'>
                      <p className='name'>
                        {student.firstName.toUpperCase()}{' '}
                        {student.lastName.toUpperCase()}
                      </p>
                      <div className='sub-details'>
                        <p>Email: {student.email}</p>
                        <p>Company: {student.company}</p>
                        <p>Skill: {student.skill}</p>
                        <p>
                          Average:{' '}
                          {student.grades.reduce(
                            (a, b) => parseInt(a) + parseInt(b),
                            0
                          ) /
                            student.grades.length +
                            '%'}
                        </p>
                        <button onClick={handleChange} className='showBtn'>
                          {btnValue}
                        </button>
                        {showData  && (
                          <div>
                            <br />
                            {student.grades.map((grade, key) => {
                              return (
                                <p key={key}>
                                  Test {key + 1}: &emsp; {grade}%
                                </p>
                              );
                            })}
                          </div>
                        )}
...

Collapse Image enter image description here

Expand Image enter image description here

Upvotes: 1

Views: 1517

Answers (1)

Giacomo
Giacomo

Reputation: 344

All the elements expand and collapse together because you assign to all of them the same state showData state.

One solution would be to add a new field to your data (so inside student) that is true or false when you want to expand or collapse the single student.

Another solution would be to create the showData state as an array where each element correspond to a different student. When you click the button, in this case, you pass to the function for example the id and with that you link your student to the right element inside the showData.

Upvotes: 1

Related Questions