Documentation
Templates
Hooks
useToggle

useToggle

Simple boolean state with toggle, on, and off functions.

Use Cases

  • Modal open/close
  • Sidebar expand/collapse
  • Show/hide password
  • Toggle switches

Code

import { useState, useCallback } from 'react';
 
interface UseToggleReturn {
  value: boolean;
  toggle: () => void;
  setTrue: () => void;
  setFalse: () => void;
  setValue: (value: boolean) => void;
}
 
export function useToggle(initialValue: boolean = false): UseToggleReturn {
  const [value, setValue] = useState(initialValue);
 
  const toggle = useCallback(() => setValue((v) => !v), []);
  const setTrue = useCallback(() => setValue(true), []);
  const setFalse = useCallback(() => setValue(false), []);
 
  return { value, toggle, setTrue, setFalse, setValue };
}

Usage

Modal

function App() {
  const modal = useToggle();
 
  return (
    <>
      <button onClick={modal.setTrue}>Open Modal</button>
 
      {modal.value && (
        <Modal onClose={modal.setFalse}>
          <h2>Modal Content</h2>
          <button onClick={modal.setFalse}>Close</button>
        </Modal>
      )}
    </>
  );
}

Password Visibility

function PasswordInput() {
  const showPassword = useToggle();
 
  return (
    <div className="relative">
      <input
        type={showPassword.value ? 'text' : 'password'}
        placeholder="Password"
      />
      <button
        type="button"
        onClick={showPassword.toggle}
        className="absolute right-2 top-1/2 -translate-y-1/2"
      >
        {showPassword.value ? <EyeOff size={16} /> : <Eye size={16} />}
      </button>
    </div>
  );
}

Sidebar

function Layout({ children }) {
  const sidebar = useToggle(true);
 
  return (
    <div className="flex">
      {sidebar.value && (
        <aside className="w-64 border-r p-4">
          Navigation
        </aside>
      )}
      <main className="flex-1 p-4">
        <button onClick={sidebar.toggle}>
          {sidebar.value ? 'Hide' : 'Show'} Sidebar
        </button>
        {children}
      </main>
    </div>
  );
}

Expandable Section

function Accordion({ title, children }) {
  const expanded = useToggle();
 
  return (
    <div className="border-b">
      <button
        onClick={expanded.toggle}
        className="flex w-full items-center justify-between py-4"
      >
        <span>{title}</span>
        <ChevronDown
          className={`h-4 w-4 transition-transform ${
            expanded.value ? 'rotate-180' : ''
          }`}
        />
      </button>
      {expanded.value && (
        <div className="pb-4">
          {children}
        </div>
      )}
    </div>
  );
}

Simple Array Version

If you prefer array destructuring:

export function useToggle(
  initialValue: boolean = false
): [boolean, () => void, (value: boolean) => void] {
  const [value, setValue] = useState(initialValue);
  const toggle = useCallback(() => setValue((v) => !v), []);
 
  return [value, toggle, setValue];
}
 
// Usage
const [isOpen, toggleOpen, setOpen] = useToggle();