react-amazing-hooks

3.1.2 • Public • Published

react-amazing-hooks

Welcome to react-amazing-hooks, a collection of custom hooks for React.js!

Each hook in this collection is designed to offer reusability and seamless integration into your projects. Happy coding!

how to install this library

Get started by installing it via npm or yarn.

npm install react-amazing-hooks
yarn add react-amazing-hooks

Docs

Hook name Description
useArray() Manage an array of items with various functions: Add, removeById, removeById, removeIndex, replaceAtIndex, replaceById, shuffle, ascendingSort, descendingSort, clear.
useUUID() Used to generate a unique identifier with high customizability and better performance.
useFieldsPopulated() Used to check if object fields are populated or empty.
useSortObjByProperty() Sort an array of objects by a property with optional ascending or descending order.
useMediaQuery() Used to check if the screen size is within a certain range. this hook can be used to conditionally render components based on screen size, or to apply different styles based on screen size.
useStorage() Used to manage state in localStorage (with optional expiration) or sessionStorage.
useBrowserLanguage() This will help you to get the browser language with optional formatting.
useCopyToClipboard() Custom hook for copying text to clipboard optional callback.
useToggle() this hook is used to toggle a boolean value with optional localStorage support.
useOnlineStatus() Detect online status with boolean value (true/false).
useWindowScroll() Tracks window scroll position with usefull information like percentage and position.
usePagination() This hook is used to paginate data. It takes an array of data and the number of items per page as arguments. It also returns some functions to navigate through the pages.
usePreviousValues() Store previous values with a limit. Default is 1 and optional "remove duplicates function" if unique is true.
useDownload() Custom hook to download text and pdf files using Blob and jsPDF library.

useArray

import { useArray } from "react-amazing-hooks";

function MyComponent() {
  const defaultArray = ["cat", "dog", "bird", { id: 2, name: "lion" }];

  const {
    add,
    clear,
    removeIndex,
    replaceAtIndex, // .. import just what you need!
    replaceById,
    shuffle,
    ascendingSort,
    descendingSort,
    value: currentArray, // renamed value to currentArray
  } = useArray(defaultArray); // the array to be manipulated

  console.log(currentArray); // result

  return (
    <>
      <button onClick={() => add("tiger")}>ADD</button>
      <button onClick={() => removeIndex(2)}>Remove</button>
      <button onClick={() => replaceById(2, "dolphin")}>Replace by ID</button>
      <button onClick={() => replaceAtIndex(3, "giraffe")}>Replace At</button>
      <button onClick={() => shuffle()}>Shuffle</button>
      <button onClick={() => ascendingSort()}>Asc Sort</button>
      <button onClick={() => descendingSort()}>Desc Sort</button>
      <button onClick={clear}>clear</button>
    </>
  );
}

export default MyComponent;

useUUID

import { useUUID, generateUUID } from "react-amazing-hooks";

const MyComponent = () => {
  const initialID = useUUID();
  // change 'myUD' and 'setMyID' with your values
  const [myID, setMyID] = useState(initialID);

  // generate a new ID with custom options
  const handleClick = () => {
    setMyID(
      generateUUID({
        prefix: "MY-CUSTOM-ID-",
        length: 15,
        specialChars: false,
        excludeChars: "12345abcde",
      })
    );
  };

  // .. or with default options
  const handleClick2 = () => {
    setMyID(generateUUID());
  };

  return (
    <div>
      <p>Initial ID: {initialID}</p>
      <p>My UUID: {myID}</p>
      <button onClick={handleClick}>CLICK</button>
      <button onClick={handleClick2}>CLICK 2</button>
    </div>
  );
};

useFieldsPopulated

import { useFieldsPopulated } from "react-amazing-hooks";

const MyComponent = () => {
  const [fields, setFields] = useState({
    name: "",
    email: "",
    age: 0,
  });

  // Checks if all fields are populated and disables the button if not
  const fieldsPopulated = useFieldsPopulated(fields);

  return (
    <>
      <input
        type="text"
        value={fields.name}
        onChange={(e) => setFields({ ...fields, name: e.target.value })}
        placeholder="Your name"
      />
      <div>
        <input
          type="email"
          value={fields.email}
          onChange={(e) => setFields({ ...fields, email: e.target.value })}
          placeholder="Your e-mail"
        />
      </div>

      <div>
        <input
          type="number"
          value={fields.age}
          onChange={(e) => setFields({ ...fields, age: e.target.value })}
          placeholder="Your age"
        />
      </div>

      <button disabled={!fieldsPopulated}>SUBMIT</button>
    </>
  );
};

export default MyComponent;

useFieldsPopulated

import { useFieldsPopulated } from "react-amazing-hooks";

const MyComponent = () => {
  const [fields, setFields] = useState({
    name: "",
    email: "",
    age: 0,
  });

  // Checks if all fields are populated and disables the button if not
  const fieldsPopulated = useFieldsPopulated(fields);

  return (
    <>
      <input
        type="text"
        value={fields.name}
        onChange={(e) => setFields({ ...fields, name: e.target.value })}
        placeholder="Your name"
      />
      <div>
        <input
          type="email"
          value={fields.email}
          onChange={(e) => setFields({ ...fields, email: e.target.value })}
          placeholder="Your e-mail"
        />
      </div>

      <div>
        <input
          type="number"
          value={fields.age}
          onChange={(e) => setFields({ ...fields, age: e.target.value })}
          placeholder="Your age"
        />
      </div>

      <button disabled={!fieldsPopulated}>SUBMIT</button>
    </>
  );
};

export default MyComponent;

useSortObjByProperty

import { useSortObjByProperty } from "react-amazing-hooks";

const MyComponent = () => {
  const data = [
    { id: 1, name: "John", age: 25 },
    { id: 2, name: "Alice", age: 30 },
    { id: 3, name: "Bob", age: 20 },
    { id: 4, name: "Doe", age: 35 },
    { id: 5, name: "Jane", age: 22 },
  ];

  const sortedData = useSortObjByProperty(
    data, // the array to sort
    "name", // the property to sort by
    "asc" // the order is: 'asc'|true  OR 'desc'|false
  );

  return (
    <>
      <ul>
        {sortedData.map((item) => (
          <li key={item.id}>
            {item.name} - {item.age}
          </li>
        ))}
      </ul>
    </>
  );
};

export default MyComponent;

useMediaQuery

import { useMediaQuery } from "react-amazing-hooks";

const MyComponent = () => {
  // just a single value
  const isMobile = useMediaQuery({ query: 550 });

  // range between 551 and 767 - 'query' will be ignored
  const isSmallTablet = useMediaQuery({ query: 551, min: 551, max: 767 });

  // range between 768 and 991
  const isTablet = useMediaQuery({ min: 768, max: 991 });
  const isLaptop = useMediaQuery({ min: 992, max: 1119 });
  const isDesktop = useMediaQuery({ min: 1120, max: 1399 });

  // range from 1400 and up. Works the same as just 'max'
  const isLargeDesktop = useMediaQuery({ min: 1400 });

  return (
    <div>
      {isMobile && <p>Mobile</p>}
      {isSmallTablet && <p>Small Tablet</p>}
      {isTablet && <p>Tablet</p>}
      {isLaptop && <p>Laptop</p>}
      {isDesktop && <p>Desktop</p>}
      {isLargeDesktop && <p>Large Desktop</p>}
    </div>
  );
};

export default MyComponent;

useStorage

// simple example:
const animals = [
  { name: "cat", sound: "meow" },
  { name: "dog", sound: "woof" },
  { name: "cow", sound: "moo" },
  { name: "pig", sound: "oink" },
  { name: "duck", sound: "quack" },
];

useStorage("animals", animals, "localStorage", 1);

// ----------------------------- //

import { useStorage } from "react-amazing-hooks";

const MyComponent = () => {
  // feel free to rename this variable name (users/setUsers)
  const [users, setUsers] = useStorage(
    "users", // key in localStorage|sessionStorage
    [
      { id: 1, name: "Marika", age: 17 },
      { id: 2, name: "Mattia", age: 70 }, // .. values to store!
      { id: 3, name: "Francesco", age: 202 },
      { id: 4, name: "Luca", age: 350 },
    ],
    "localStorage", // localStorage|sessionStorage
    7 // expires in 7 days
  );

  const updateUser = () => {
    const updatedUsers = users.map((user) => {
      if (user.id === 1) {
        // ... this specific user with id === 1
        return { ...user, age: 18 }; // age 17 -> .. changed to 18!
      }
      return user;
    });
    setUsers(updatedUsers); // this will update the state and storage
  };

  return (
    <div>
      {users &&
        users.map((user) => (
          <div key={user.id}>
            <p>{user.name}</p>
            <p>{user.age}</p>
          </div>
        ))}
      <button onClick={updateUser}>Update user</button>
    </div>
  );
};

export default MyComponent;

useBrowserLanguage

import { useBrowserLanguage } from "react-amazing-hooks";

const MyComponent = () => {
  // the first parameter is the format: 'short', 'extend'
  // the second parameter is the text format: 'uppercase', 'capitalize', or 'lowercase'
  const example1 = useBrowserLanguage("extend", "lowercase");
  const example2 = useBrowserLanguage(undefined, "uppercase"); // --> 'short'
  const example3 = useBrowserLanguage("short", "capitalize");

  // ... the rest of your code here!
};

export default MyComponent;

useCopyToClipboard

import { useCopyToClipboard } from "react-amazing-hooks";

const MyComponent = () => {
  const [inputValue, setInputValue] = useState("");

  // my custom callback function
  const myAmazingCallBack = () => {
    console.log("this is just an example callback function");
  };

  // function to handle input change
  const handleInputChange = (event) => {
    setInputValue(event.target.value);
  };

  // use the custom hook with or without a callback function
  const copyToClipboard = useCopyToClipboard(myAmazingCallBack);
  const copyToClipboardWithNoCallback = useCopyToClipboard();

  return (
    <>
      <input type="text" value={inputValue} onChange={handleInputChange} />
      <div>
        <button onClick={() => copyToClipboard(inputValue)}>
          Copy to Clipboard
        </button>
        <button onClick={() => copyToClipboardWithNoCallback(inputValue)}>
          Copy to Clipboard 2
        </button>
      </div>
    </>
  );
};

export default MyComponent;

useToggle

import { useToggle } from "react-amazing-hooks";

const MyComponent = () => {
  // feel free to change the initialValue and localStorageKey and to import just what you need!
  const { value, toggle, setValueTo, reset, isValue } = useToggle(
    false, // initialValue
    "myToggle" // localStorageKey
  );

  return (
    <div>
      {/* Display the current value */}
      <p>Current Value: {value.toString()}</p>

      {/* Button to toggle the value */}
      <button onClick={toggle}>Toggle</button>

      {/* Button to set the value to true */}
      <button onClick={() => setValueTo(true)}>Set to True</button>

      {/* Button to set the value to false */}
      <button onClick={() => setValueTo(false)}>Set to False</button>

      {/* Button to reset the value to the initial value */}
      <button onClick={reset}>Reset</button>

      {/* Check if the value is true */}
      {isValue(true) && <p>The value is true</p>}

      {/* Check if the value is false */}
      {isValue(false) && <p>The value is false</p>}
    </div>
  );
};

export default MyComponent;

useOnlineStatus

import { useOnlineStatus } from "react-amazing-hooks";

const MyComponent = () => {
  const onlineStatus = useOnlineStatus();

  return (
    <>
      <p>{onlineStatus ? "You are online!" : "You are offline.."}</p>
    </>
  );
};

export default MyComponent;

useWindowScroll

import { useWindowScroll } from "react-amazing-hooks";

const MyComponent = () => {
  // .. import just what you need!
  const { x, y, percentageX, percentageY } = useWindowScroll();

  return (
    <>
      <div>
        <p>Horizontal position: {x}</p>
        <p>Vertical position: {y}</p>
        <p>Percentage of horizontal scrolling: {percentageX}%</p>
        <p>Percentage of vertical scrolling {percentageY}%</p>
      </div>
    </>
  );
};

export default MyComponent;

usePagination

import { usePagination } from "react-amazing-hooks";

const MyComponent = () => {
  const myData = [
    { id: 1, name: "Oggetto 1" },
    { id: 2, name: "Item 2" },
    { id: 3, name: "Item 3" },
    { id: 4, name: "Item 4" },
    { id: 5, name: "Item 5" },
    { id: 6, name: "Item 6" },
    { id: 7, name: "Item 7" },
    { id: 8, name: "Item 8" },
    { id: 9, name: "Item 9" },
    { id: 10, name: "Item 10" },
  ];

  const {
    paginatedData, // data for the current page
    currentPage, // this rappresent the current page number (number)
    totalPages, // how many pages in total (number)
    goToPage, // go to a specific page with a number argument (function)
    nextPage, // go to the next page (function)
    prevPage, // go to go to the previous page (function)
    goToFirstPage, // go to the first page (function)
    goToLastPage, // go to the last page (function)
  } = usePagination(myData, 5); // .. example: 5 items per page

  return (
    <div>
      {/* render your paginated data here */}
      {paginatedData.map((item, index) => (
        <div key={index}>{item}</div>
      ))}
      {/* pagination controls. This is just an example, you can style it as you like or use other controls */}
      <button onClick={goToFirstPage} disabled={currentPage === 1}>
        First
      </button>
      <button onClick={prevPage} disabled={currentPage === 1}>
        Previous
      </button>
      <span style={{ margin: "0 10px" }}>
        {currentPage} of {totalPages}
      </span>
      <button onClick={nextPage} disabled={currentPage === totalPages}>
        Next
      </button>
      <button onClick={goToLastPage} disabled={currentPage === totalPages}>
        Last
      </button>

      {/* since the goToPage function requires a number as an argument, you can use an arrow function */}
      <button onClick={() => goToPage(3)} disabled={currentPage === totalPages}>
        Go to page 3
      </button>
    </div>
  );
};
export default MyComponent;

usePreviousValues

import { usePreviousValues } from "react-amazing-hooks";

const MyComponent = () => {
  const [value, setValue] = useState("React.js");
  const { previousValue } = usePreviousValues(
    value, // the value to store as previous value
    3, // how many previous values to store
    true // remove duplicates. Default is false
  );

  return (
    <>
      <div>
        <p>
          My favourite JS framework is: <b>{value}</b>
        </p>
        <ul>
          {previousValue.map((item, index) => (
            <li key={index}>{item}</li>
          ))}
        </ul>
      </div>
      <div>
        <button onClick={() => setValue("React.js")}>React.js</button>
        <button onClick={() => setValue("Svelte")}>Svelte</button>
        <button onClick={() => setValue("Next.js")}>Next.js</button>
        <button onClick={() => setValue("Angular")}>Angular</button>
        <button onClick={() => setValue("Vue.js")}>Vue.js</button>
      </div>
    </>
  );
};

export default MyComponent;

useDownload

import { useDownload } from "react-amazing-hooks";

const MyComponent = () => {
  const { downloadPDF, downloadTxt } = useDownload();
  const content = "This is my content that I want to include in the file";
  const fileName = "amazing-file";

  const handleClickPDF = () => {
    downloadPDF(fileName, content);
  };

  const handleClickTXT = () => {
    downloadTxt(fileName, content);
  };

  return (
    <div>
      <button onClick={handleClickPDF}>Download PDF</button>
      <button onClick={handleClickTXT}>Download TXT</button>
    </div>
  );
};

export default MyComponent;

useHover

import { useHover } from "react-amazing-hooks";

const MyComponent = () => {
  const ulRef = useRef(null);

  /* ---------------------- 
 
Custom options object to extend the useHover hook:
  const options = {
    delay: 200, // delay before the hover is considered active
    onHoverStart: () => console.log("Hover started"), // callback function when the hover starts
    onHoverEnd: () => console.log("Hover ended") // callback function when the hover ends
  };
 
  const isHoveredId = useHover('#myId', options);    <---- options object passed as the second argument
  const isHoveredClass = useHover('.myClass', options);
  const isHoveredRef = useHover(ulRef, options); 

*/

  // Using useHover to detect if an element is hovered with..
  const isHoveredId = useHover("#myId"); // .. ID
  const isHoveredClass = useHover(".myClass"); // .. class
  const isHoveredRef = useHover(ulRef); // .. ref

  return (
    <>
      <div>
        <ul>
          <li
            className={`myClass ${
              isHoveredClass ? "custom-class1" : "custom-class-2"
            }`}
          >
            Anakin Skywalker
          </li>
          <li
            id="myId"
            className={`${isHoveredId ? "custom-class1" : "custom-class-2"}`}
          >
            R2-D2
          </li>
          <li
            ref={ulRef}
            className={`${isHoveredRef ? "custom-class1" : "custom-class-2"}`}
          >
            Obi-Wan Kenobi
          </li>
        </ul>
      </div>
      <div>
        <p>{isHoveredClass && "Is Anakin Skywalker your favorite? 😁"}</p>
        <p>{isHoveredId && "Mine is R2-D2! 🤖"}</p>
        <p>{isHoveredRef && "Obi-Wan Kenobi is a good choice too! 👌"}</p>
      </div>
    </>
  );
};

export default MyComponent;

Package Sidebar

Install

npm i react-amazing-hooks

Weekly Downloads

397

Version

3.1.2

License

MIT

Unpacked Size

46.3 kB

Total Files

22

Last publish

Collaborators

  • mattiach