npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

custom-react-hook-library

v1.0.2

Published

A collection of reusable custom React hooks for state management, side effects, and more.

Downloads

20

Readme

React Custom Hooks Collection

A collection of lightweight, reusable React hooks for common UI patterns and functionalities.

npm version License: MIT TypeScript PRs Welcome

Installation

npm install react-custom-hooks-collection
# or
yarn add react-custom-hooks-collection
# or
pnpm add react-custom-hooks-collection

Hooks Overview

  • useToggle - Toggle boolean states
  • useForm - Form state management
  • useLocalStorage - Local storage state management
  • useClickOutside - Detect clicks outside elements
  • useMediaQuery - Responsive media queries
  • useDebounce - Debounce values
  • useFetch - Data fetching with cache
  • useKeyPress - Keyboard event handling
  • usePagination - Pagination logic
  • useInfiniteScroll - Infinite scrolling
  • useClipboard - Clipboard operations
  • useHistory - State history management

Usage Examples

useToggle

Simple boolean state toggle.

import { useToggle } from 'react-custom-hooks-collection';

const ToggleExample = () => {
  const [isOn, toggle] = useToggle(false);

  return (
    <button onClick={toggle}>
      {isOn ? 'Turn Off' : 'Turn On'}
    </button>
  );
};

useForm

Form state management with validation.

import { useForm } from 'react-custom-hooks-collection';

const FormExample = () => {
  const { values, errors, handleChange, handleSubmit } = useForm({
    initialValues: {
      email: '',
      password: ''
    },
    validate: (values) => {
      const errors: Record<string, string> = {};
      if (!values.email) errors.email = 'Required';
      if (!values.password) errors.password = 'Required';
      return errors;
    },
    onSubmit: (values) => {
      console.log(values);
    }
  });

  return (
    <form onSubmit={handleSubmit}>
      <input
        name="email"
        value={values.email}
        onChange={handleChange}
      />
      {errors.email && <span>{errors.email}</span>}
      
      <input
        name="password"
        type="password"
        value={values.password}
        onChange={handleChange}
      />
      {errors.password && <span>{errors.password}</span>}
      
      <button type="submit">Submit</button>
    </form>
  );
};

useLocalStorage

Persist state in localStorage.

import { useLocalStorage } from 'react-custom-hooks-collection';

const LocalStorageExample = () => {
  const [user, setUser] = useLocalStorage('user', null);

  return (
    <div>
      <button onClick={() => setUser({ name: 'John' })}>
        Set User
      </button>
      <p>User: {JSON.stringify(user)}</p>
    </div>
  );
};

useClickOutside

Detect clicks outside an element.

import { useClickOutside } from 'react-custom-hooks-collection';

const ModalExample = () => {
  const [isOpen, setIsOpen] = useState(false);
  const modalRef = useClickOutside(() => setIsOpen(false));

  return (
    <>
      <button onClick={() => setIsOpen(true)}>Open Modal</button>
      {isOpen && (
        <div ref={modalRef}>
          Modal Content
        </div>
      )}
    </>
  );
};

useMediaQuery

Responsive design with media queries.

import { useMediaQuery } from 'react-custom-hooks-collection';

const ResponsiveExample = () => {
  const isMobile = useMediaQuery('(max-width: 768px)');
  const isTablet = useMediaQuery('(min-width: 769px) and (max-width: 1024px)');

  return (
    <div>
      {isMobile && <MobileLayout />}
      {isTablet && <TabletLayout />}
      {!isMobile && !isTablet && <DesktopLayout />}
    </div>
  );
};

useDebounce

Debounce rapidly changing values.

import { useDebounce } from 'react-custom-hooks-collection';

const SearchExample = () => {
  const [search, setSearch] = useState('');
  const debouncedSearch = useDebounce(search, 500);

  useEffect(() => {
    // API call with debouncedSearch
  }, [debouncedSearch]);

  return (
    <input
      value={search}
      onChange={(e) => setSearch(e.target.value)}
      placeholder="Search..."
    />
  );
};

useFetch

Data fetching with caching.

import { useFetch } from 'react-custom-hooks-collection';

const DataFetchingExample = () => {
  const { data, error, loading, refetch } = useFetch<User[]>('/api/users');

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      <button onClick={refetch}>Refresh</button>
      {data?.map(user => (
        <div key={user.id}>{user.name}</div>
      ))}
    </div>
  );
};

useKeyPress

Keyboard event handling.

import { useKeyPress } from 'react-custom-hooks-collection';

const ShortcutExample = () => {
  useKeyPress('Escape', () => {
    console.log('Escape pressed');
  });

  useKeyPress('Enter', () => {
    console.log('Enter pressed');
  });

  return <div>Press Escape or Enter</div>;
};

usePagination

Pagination logic.

import { usePagination } from 'react-custom-hooks-collection';

const PaginationExample = () => {
  const {
    currentPage,
    totalPages,
    nextPage,
    prevPage,
    setPage,
    currentItems
  } = usePagination(items, 10);

  return (
    <div>
      {currentItems.map(item => (
        <div key={item.id}>{item.name}</div>
      ))}
      <div>
        <button onClick={prevPage}>Previous</button>
        <span>Page {currentPage} of {totalPages}</span>
        <button onClick={nextPage}>Next</button>
      </div>
    </div>
  );
};

useInfiniteScroll

Infinite scrolling functionality.

import { useInfiniteScroll } from 'react-custom-hooks-collection';

const InfiniteListExample = () => {
  const [items, setItems] = useState<Item[]>([]);
  const isFetching = useInfiniteScroll(loadMore);

  async function loadMore() {
    const newItems = await fetchMoreItems();
    setItems(prev => [...prev, ...newItems]);
  }

  return (
    <div>
      {items.map(item => (
        <div key={item.id}>{item.name}</div>
      ))}
      {isFetching && <div>Loading more...</div>}
    </div>
  );
};

useClipboard

Clipboard operations.

import { useClipboard } from 'react-custom-hooks-collection';

const ClipboardExample = () => {
  const { copy, paste, copiedText, error } = useClipboard();

  return (
    <div>
      <button onClick={() => copy('Hello, World!')}>
        Copy Text
      </button>
      <button onClick={async () => {
        const text = await paste();
        console.log('Pasted:', text);
      }}>
        Paste
      </button>
      {copiedText && <div>Copied: {copiedText}</div>}
      {error && <div>Error: {error.message}</div>}
    </div>
  );
};

useHistory

State history with undo/redo.

import { useHistory } from 'react-custom-hooks-collection';

const EditorExample = () => {
  const [content, setContent, undo, redo] = useHistory('');

  return (
    <div>
      <textarea
        value={content}
        onChange={(e) => setContent(e.target.value)}
      />
      <button onClick={undo}>Undo</button>
      <button onClick={redo}>Redo</button>
    </div>
  );
};

Type Definitions

All hooks are written in TypeScript and include comprehensive type definitions.

Contributing

Contributions are welcome! Please read our contributing guide for details on our code of conduct, and the process for submitting pull requests.

License

MIT © [Your Name]

Support

If you find this package helpful, please ⭐️ it on GitHub.