Select multiple Items feature: How did I implement it using a custom use-checkbox hook?

Select multiple Items feature: How did I implement it using a custom use-checkbox hook?

Managing the state of multiple checkboxes across a dynamic UI can quickly become challenging, especially in React applications. Recently, I faced this challenge while working on an awesomescreenshot clone—an attempt to replicate the "select multiple items" feature (the ability to select both folders and images/videos). To simplify the process, I created a reusable hook, useCheckboxStates. In this article, I'll walk you through how I implemented it and why it might be useful for your projects.

Due to the nature of the application, I needed a solution that allowed dynamic selection of both folders and images/videos. Additionally, this feature had to be reusable across other parts of the application, such as the /trash route.

To achieve this, I built a custom React hook that manages checkbox states and provides helper functions for updates, counts, and resets—all while responding to route changes.

The implementation is broken down into five sections:

  1. State Management

const [checkedStates, setCheckedStates] = useState(initialState); 
const [checkedIds, setCheckedIds] = useState([]);        

Here, I used React's useState hook to store the states of the checkboxes and their corresponding IDs.

2. The handleCheckboxChange Function

const handleCheckboxChange = (id, checked, docType) => {
  setCheckedStates((prev) => ({
    ...prev,
    [id]: checked,
  }));

  // Update the checkedIds array
  setCheckedIds((prevIds) => {
    if (checked) {
      return [...prevIds, { id, docType }];
    } else {
      return prevIds.filter((item) => item.id !== id);
    }
  });
};        

The handleCheckboxChange function toggles the state of a clicked checkbox. It accepts the item's ID, checkbox status (true/false), and an optional docType.

  • setCheckedStates: Stores the state of the checkbox item, appending the state to a specific item ID.
  • setCheckedIds: Updates the checkedIDs array to add or remove an item based on whether the checkbox is checked or unchecked.

Note: The docType is optional. In this case, I use it to distinguish between folders and documents (images/videos)

3. Memoized Count (optional)

const checkedCount = useMemo(() => checkedIds.length, [checkedIds]);        

This function counts the number of checked items. The useMemo hook ensures that checkedCount only recalculates if the checkedIDs array changes.

4. Pathname Changes (Optional)

const pathname = usePathname();
useEffect(() => {
  resetCheckBox();
}, [pathname]);        

Here, If the user navigates to a new route, the resetCheckBox function clears all selected checkbox states.

5. Export Utility functions

return {
  checkedStates,
  checkedIds,
  checkedCount,
  handleCheckboxChange,
  resetCheckBox,
};        

The complete code snippet.

import { usePathname } from "next/navigation";
import { useEffect, useMemo, useState } from "react";

const useCheckboxStates = (initialState = {}) => {
  const [checkedStates, setCheckedStates] = useState(initialState);
  const [checkedIds, setCheckedIds] = useState([]);
  const pathname = usePathname();

  /**
   * Handle the checkbox state
   * @param {string} id - The ID of the folder or document.
   * @param {boolean} checked - The state of the checkbox.
   * @param {string} docType - Either "folder" or "document".
   */
  const handleCheckboxChange = (id, checked, docType) => {
    setCheckedStates((prev) => ({
      ...prev,
      [id]: checked,
    }));

    setCheckedIds((prevIds) => {
      if (checked) {
        return [...prevIds, { id, docType }];
      } else {
        return prevIds.filter((item) => item.id !== id);
      }
    });
  };

  const resetCheckBox = () => {
    setCheckedStates({});
    setCheckedIds([]);
  };

  const checkedCount = useMemo(() => checkedIds.length, [checkedIds]);

  useEffect(() => {
    resetCheckBox();
  }, [pathname]);

  return {
    checkedStates,
    checkedIds,
    checkedCount,
    handleCheckboxChange,
    resetCheckBox,
  };
};
        

Usage Example.

<Checkbox
  checked={isChecked}
  onCheckedChange={(checked) =>
    handleCheckboxChange(item.id, checked, "document") // "document" or "folder"
  }
/>        

Thank you for your time!

Eke Olise

Customer Relationship Manager | Operations Specialist | Product Manager

2 个月

Very resourcesful article. Weldon Deede

回复
Uzomba Ogechi

Student at Federal polytechnic nekede

2 个月

?? nice

Oyeshiku David

Student at Federal polytechnic Nekede, Owerri

2 个月

Very helpful

Anuforo Okechukwu Deede

Experienced Software Engineer | Optimizing React applications to increase performance and scalability | AI Enthusiast

2 个月
回复
Anuforo Okechukwu Deede

Experienced Software Engineer | Optimizing React applications to increase performance and scalability | AI Enthusiast

2 个月
回复

要查看或添加评论,请登录

Anuforo Okechukwu Deede的更多文章

社区洞察

其他会员也浏览了