简体   繁体   中英

Implement show more button in table using React Hooks

I'm trying to implement show more button on the table with clients and theirs projects. This is my code

<tbody className="text-gray-700">
  {clients.map((client, i) => (
    <tr key={i} className="border-b-2">
      <td className="pl-2">
        <div className="flex flex-col">
          <span className="ml-3 text-lg font-bold">{client.name} </span>
        </div>
      </td>

      <td className="text-center">
        {projects
          .filter((project) => project.client_id === client.id)
          .slice(0, numberOfItems)
          .map((filterProject, key) => (
            <div key={filterProject.id} className="text-left mb-1 w-2/3">
              <div className="cursor-pointer text-base">
                {filterProject.label}
              </div>
            </div>
          ))}
        <a
          className=" text-buttonColor float-left text-left cursor-pointer text-sm"
          onClick={() => setShowMore(!showMore)}
        >
          click for more
        </a>
      </td>
    </tr>
  ))}
</tbody>

where

const [ showMore, setShowMore ] = useState(false)
const numberOfItems = showMore ? projects.length : 3

The problem is when I click on show more all projects of all clients are shown, and I need to show all projects of only one client which is clicked. Anyone have idea how to correct this?

One way would be to just change showMore to use numbers instead of true/false. Set it to -1 at the start and change it to the iterator of your map function: onClick = {(i)=>setShowMore(i)}

Then all you have to do is check if i === showMore before showing more.

Just set it back to -1 when you want to remove whatever the more is that you are showing

The showMore state should hold the id of the client that you currently wish to expend, and null if none.

const [ showMore, setShowMore ] = useState(null)

Then you can slice the number of viewed projects for a client accordingly:

<td className="text-center">
  {projects
    .filter((project) => project.client_id === client.id)
    .slice(0, showMore === client.id ? projects.length : 3) // slice according to the selected id
    .map((filterProject, key) => (
      <div key={filterProject.id} className="text-left mb-1 w-2/3">
        <div className="cursor-pointer text-base">
          {filterProject.label}
        </div>
      </div>
    ))}
  <a
    className=" text-buttonColor float-left text-left cursor-pointer text-sm"
    onClick={() => setShowMore(showMore === null ? client.id : null)}  // set the currently expended item
  >
    click for more
  </a>
</td>

I write sandbox for your implementation

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM