Skip to content

F. Custom Hook

Selain hook yang disediakan oleh reactjs, kita juga bisa membuat hook kita sendiri atau yang bisa disebut dengan custom hook.

custom hook memungkinkan kita untuk membuat hook untuk fungsi tertentu dengan logika yang kita buat sendiri. Dengan membuat custom hook, kita bisa membuat function yang bisa digunakan berulang-ulang seperti layakanya membuat komponen.

Pada contoh di bawah ini, kita akan pelajari bagimana membuat custom hook.

1. Contoh 1 membuat useDisclosure

Pada kode yang diblok dibawah. Kita membuat state isOpen dan membuat function onOpen dan onClose. Dimana function onOpen ketika dipanggil akan merubah nilai isOpen menjadi true sedangkan onClose akan membuat isOpen menjadi false.

app/page.tsx
"use client";
import { useRef, useState } from "react";
import Button from "../components/Button";


const Home = () => {
  let [isOpen, setIsOpen] = useState<boolean>(false);

  const onOpen = () => {
    setIsOpen(true);
  };

  const onClose = () => {
    setIsOpen(false);
  };

  return (
    <section className="h-screen w-screen space-y-5">
     <Button onClick={onOpen} colorSchema="blue" title="open" />
     <Button onClick={onClose} colorSchema="red" title="closed" />


     {isOpen ? <p>Open</p> : <p>Close</p>}

    </section>
  );
};

export default Home;

Jalankan pada Browser

Alt text

Kode dengan fungsi seperti itu bisa dibutuhkan di banyak komponen. Tentu memungkinkan kita untuk menulis kode berkali-kali. untuk menghindari hal tersebut maka kode di atas kita jadikan sebagai Custom Hook

Dalam Project react , biasanya kita akan membuat folder dengan nama hook yang nantinya akan berisi kode-kode dari custom hook yang kita buat. Pada contoh ini, kita akan membuat custom hook dengan nama useDisclosure

Note

Dalam membaut custom hook nama dari custom hook harus dimulai dengan keyword use

Jalankan pada Browser

Alt text

Membuat useDisclosure

hook/useDisclosure.ts
import { useState } from "react";

export const useDisclosure = () => {
  let [isOpen, setIsOpen] = useState<boolean>(false);

  const onOpen = () => {
    setIsOpen(!isOpen);
  };

  const onClose = () => {
    setIsOpen(false);
  };

  return { onOpen, onClose, isOpen };
};
hook/index.ts
export * from './useDisclosure'

Pindahkan state , onOpen, onClose dari file app/page.tsx ke file useDisclosure seperti pada kode di atas.

Memanggil hook useDisclosure pada komponen

app/page.tsx
"use client";
import { useRef, useState } from "react";
import Button from "../components/Button";
import { useDisclosure } from "@/hook";


const Home = () => {
  const {isOpen, onOpen, onClose} = useDisclosure()

  return (
    <section className="h-screen w-screen space-y-5">
     <Button onClick={onOpen} colorSchema="blue" title="open" />
     <Button onClick={onClose} colorSchema="red" title="closed" />


     {isOpen ? <p>Open</p> : <p>Close</p>}

    </section>
  );
};

export default Home;

Pada kode di atas, contoh bagaimana memanggil custom hook pada komponen.

Jalankan pada Browser

Alt text

2. Contoh 2 membuat useDebounce

Pada kode di bawah kita akan membuat suatu fungsi untuk menerapkan delay sebelum memproses nilai sebelum berubah.

app/page.tsx
"use client";
import { useEffect, useRef, useState } from "react";
import Button from "@/component/Button";
import useDislosure from "@/hook/useDisclosure";
import InputText from "@/component/InputText";
import useDislosure from "@/hook/useDisclosure";

const Home = () => {
  const [keyword, setKeyword] = useState("");
  const { isOpen, onOpen, onClose } = useDislosure();
  const [debouncedValue, setDebouncedValue] = useState("");
  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(keyword);
    }, 1000);

    return () => {
      clearTimeout(handler);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [keyword]);

  return (
    <section className="h-screen w-screen space-y-5">
      <Button onClick={onOpen} colorSchema="blue" title="open" />
      <Button onClick={onClose} colorSchema="red" title="closed" />
      <InputText
        value={keyword}
        onChange={(e) => {
          setKeyword(e.target.value);
        }}
      />

      {debouncedValue}

      {isOpen ? <p>Open</p> : <p>Close</p>}
    </section>
  );
};

export default Home;

Membuat useDebounce

Alt text

hook/useDebounce
import { useEffect, useState } from "react";

export default function useDebounce(value: string, delay: number) {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

    return () => {
      clearTimeout(handler);
    };
  }, [value, delay]);

  return {debouncedValue}
}

Memanggil hook useDebounce pada komponen

app/page.tsx
"use client";
import { useEffect, useRef, useState } from "react";
import Button from "@/component/Button";
import useClosure from "@/hook/useDisclosure";
import InputText from "@/component/InputText";
import useDebounce from "@/hook/useDebounce";
import useDislosure from "@/hook/useDisclosure";

const Home = () => {
  const [keyword, setKeyword] = useState("");
  const { debouncedValue } = useDebounce(keyword, 1000);
  const { isOpen, onOpen, onClose } = useDislosure();

  return (
    <section className="h-screen w-screen space-y-5">
      <Button onClick={onOpen} colorSchema="blue" title="open" />
      <Button onClick={onClose} colorSchema="red" title="closed" />
      <InputText
        placeholder="ketika"
        value={keyword}
        onChange={(e) => {
          setKeyword(e.target.value);
        }}
      />

      {debouncedValue}

      {isOpen ? <p>Open</p> : <p>Close</p>}
    </section>
  );
};

export default Home;

Note

Dengan membuat custom hook kita tidak perlu berkali-kali membuat kode dengan fungsi yang sama pada setiap komponen