September 20, 2026

Membuat Keyboard Shortcut di React.

Cara membangun custom hook untuk menangani keyboard shortcut di aplikasi React, termasuk kombinasi tombol dan mencegah konflik dengan input form.

Keyboard shortcut membuat aplikasi terasa jauh lebih cepat dipakai oleh pengguna yang terbiasa dengan keyboard, seperti Cmd+K untuk pencarian atau Esc untuk menutup modal. Berikut cara membangunnya sebagai custom hook yang bisa dipakai ulang di React.

Menangani Event Keyboard Dasar

useEffect(() => {
  function tanganiTombol(event) {
    if (event.key === "Escape") {
      tutupModal();
    }
  }

  window.addEventListener("keydown", tanganiTombol);
  return () => window.removeEventListener("keydown", tanganiTombol);
}, []);

Membersihkan event listener di fungsi return dari useEffect penting dilakukan agar listener tidak menumpuk setiap kali komponen dirender ulang.

Membuat Custom Hook useKeyboardShortcut

function useKeyboardShortcut(kombinasi, callback) {
  useEffect(() => {
    function tanganiTombol(event) {
      const tombolCocok = kombinasi.every((tombol) => {
        if (tombol === "ctrl") return event.ctrlKey || event.metaKey;
        if (tombol === "shift") return event.shiftKey;
        return event.key.toLowerCase() === tombol.toLowerCase();
      });

      if (tombolCocok) {
        event.preventDefault();
        callback();
      }
    }

    window.addEventListener("keydown", tanganiTombol);
    return () => window.removeEventListener("keydown", tanganiTombol);
  }, [kombinasi, callback]);
}

Memakai Hook di Komponen

function AplikasiPencarian() {
  const [terbuka, setTerbuka] = useState(false);

  useKeyboardShortcut(["ctrl", "k"], () => setTerbuka(true));
  useKeyboardShortcut(["Escape"], () => setTerbuka(false));

  return terbuka ? <ModalPencarian /> : null;
}

Dengan pola ini, Cmd+K (di Mac) atau Ctrl+K (di Windows/Linux) membuka modal pencarian, sedangkan Esc menutupnya — cukup dengan dua baris deklaratif di komponen.

Menghindari Konflik dengan Input Form

Shortcut global perlu berhati-hati agar tidak mengganggu pengguna yang sedang mengetik di dalam form.

function useKeyboardShortcut(kombinasi, callback) {
  useEffect(() => {
    function tanganiTombol(event) {
      const sedangMengetik = ["INPUT", "TEXTAREA"].includes(
        event.target.tagName
      );

      if (sedangMengetik) return;

      const tombolCocok = kombinasi.every((tombol) => {
        if (tombol === "ctrl") return event.ctrlKey || event.metaKey;
        return event.key.toLowerCase() === tombol.toLowerCase();
      });

      if (tombolCocok) {
        event.preventDefault();
        callback();
      }
    }

    window.addEventListener("keydown", tanganiTombol);
    return () => window.removeEventListener("keydown", tanganiTombol);
  }, [kombinasi, callback]);
}

Menampilkan Petunjuk Shortcut ke Pengguna

function PetunjukShortcut() {
  const isMac = navigator.platform.toUpperCase().includes("MAC");

  return (
    <span className="petunjuk">
      Tekan {isMac ? "⌘" : "Ctrl"}+K untuk mencari
    </span>
  );
}

Menyesuaikan tampilan simbol shortcut berdasarkan sistem operasi membuat petunjuk terasa lebih natural bagi pengguna Mac maupun Windows.

Kesimpulan

Custom hook seperti useKeyboardShortcut membungkus logika event listener yang berulang menjadi satu API deklaratif yang mudah dipakai ulang di banyak komponen. Yang perlu selalu diperhatikan: bersihkan listener saat komponen di-unmount, dan hindari shortcut global mengganggu pengguna yang sedang mengetik di dalam form.

Hey! I’m Fanny, the software engineer tending to this digital garden. You can read more about me, or subscribe by email.

Comments