+3

7 Custom Hooks Cực Hay Mà Mọi Frontend Developer Nên Bỏ Túi

Anh em chắc quá quen với việc viết custom hook cho dự án và mỗi anh em có trong túi bộ custom hook hay dùng của mình

Hôm nay mình muốn chia sẻ về một thư viện hooks có code sẵn cực kỳ tiện lợi mà có thể sẽ giúp anh em code nhanh hơn mà không cần code lại nhiều. Đó chính là useHooks - một nơi tổng hợp các custom React Hooks cực ngon và có sẵn trên npm.

Vậy nó là gì, có gì hot? bắt đầu thôi!!! 😄😄😄


Nếu thấy hay thì cho mình xin một bookmark ở phía bên trái để bài viết đến được nhiều người hơn nha

Chúng mình có tạo Group cho các bạn cùng chia sẻ và học hỏi về frontend nâng cao, các câu phỏng vấn khó nha 😄😄😄

Các bạn tham gia để gây dựng cộng đồng Frontend Việt Nam thật lớn mạnh nhé 😍😍😍

Cộng Đồng Frontend Nâng Cao Việt Nam: https://www.facebook.com/groups/seniorfrontendvietnam

Kênh TikTok: https://www.tiktok.com/@sydexa.com

Kênh youtube: https://www.youtube.com/@sydexa.official

Nếu thấy hay thì cho mình xin một bookmark ở phía bên trái để bài viết đến được nhiều người hơn nha


Giới Thiệu Về useHooks

Nó là.... 1 bộ thư viện sẵn các custom hook hay ho mà anh em trên toàn thế giới đang dùng

https://usehooks.com/

image.png

Cài Đặt

Đơn giản chỉ cần chạy:

npm i @uidotdev/usehooks

Cùng điểm qua 7 Hooks hay dùng trong bộ này nha

Mình sẽ đi qua từng hook một, giải thích công dụng và cách sử dụng nhé!

1. useMediaQuery - Xử Lý Responsive Design Dễ Dàng

Hook này giúp detect CSS media queries một cách real-time. Cực kỳ hữu ích cho responsive design!

Use case phổ biến:

  • Render UI khác nhau theo kích thước màn hình
  • Điều chỉnh layout cho mobile/tablet/desktop
  • Conditional rendering dựa trên viewport

Ví dụ:

import { useMediaQuery } from "@uidotdev/usehooks";

export default function App() {
  const isSmallDevice = useMediaQuery("only screen and (max-width : 768px)");
  const isMediumDevice = useMediaQuery(
    "only screen and (min-width : 769px) and (max-width : 992px)"
  );
  const isLargeDevice = useMediaQuery(
    "only screen and (min-width : 993px) and (max-width : 1200px)"
  );
  const isExtraLargeDevice = useMediaQuery(
    "only screen and (min-width : 1201px)"
  );

  return (
    <section>
      <h1>useMediaQuery Demo</h1>
      {isSmallDevice && <div>Màn hình nhỏ ≤ 768px</div>}
      {isMediumDevice && <div>Màn hình trung bình: 769px - 992px</div>}
      {isLargeDevice && <div>Màn hình lớn: 993px - 1200px</div>}
      {isExtraLargeDevice && <div>Màn hình rất lớn ≥ 1201px</div>}
    </section>
  );
}

Lưu ý: Hook này chỉ chạy client-side (browser), không dùng được server-side nha!

2. useHover - Xử Lý Hover Effects

Khi anh em muốn tạo hiệu ứng hover mà không cần phải viết nhiều CSS? Hook này giúp anh em detect khi user hover vào element một cách dễ dàng.

Use case:

  • Hover animations
  • Interactive UI elements
  • Hiển thị tooltips

Ví dụ:

import { useHover } from "@uidotdev/usehooks";

function getRandomColor() {
  const colors = ["#10b981", "#3b82f6", "#a855f7", "#ef4444", "#ec4899"];
  return colors[Math.floor(Math.random() * colors.length)];
}

export default function App() {
  const [ref, hovering] = useHover();
  const backgroundColor = hovering ? getRandomColor() : "#374151";

  return (
    <div
      ref={ref}
      style={{
        backgroundColor,
        width: "300px",
        height: "150px",
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
      }}
    >
      Đang hover? {hovering ? "Có" : "Không"}
    </div>
  );
}

3. useCopyToClipboard - Copy Văn Bản Cực Dễ

Chức năng copy to clipboard là must-have trong nhiều app. Hook này giúp implement feature đó cực nhanh!

Use case:

  • Copy API keys
  • Copy mã code
  • Copy links, referral codes
  • Copy bất kỳ text nào

Ví dụ:

import { useCopyToClipboard } from "@uidotdev/usehooks";

const randomHash = crypto.randomUUID();

export default function App() {
  const [copiedText, copyToClipboard] = useCopyToClipboard();
  const hasCopiedText = Boolean(copiedText);

  return (
    <section>
      <h1>Copy API Key</h1>
      <pre>
        <code>{randomHash}</code>
        <button
          disabled={hasCopiedText}
          onClick={() => copyToClipboard(randomHash)}
        >
          {hasCopiedText ? "Đã copy ✓" : "Copy"}
        </button>
      </pre>
      {hasCopiedText && (
        <div>
          <h4>Copied thành công 🎉</h4>
          <textarea placeholder="Paste vào đây thử xem" />
        </div>
      )}
    </section>
  );
}

Hook này tự động fallback sang document.execCommand("copy") nếu navigator.clipboard không khả dụng. Smart!

4. useToggle - Toggle State Đơn Giản

Toggle on/off là pattern cực kỳ phổ biến. Hook này giúp quản lý boolean state một cách vô cùng clean

Use case:

  • Show/hide modals
  • Toggle sidebar/menu
  • Dark/light mode
  • Expand/collapse sections
  • Show more/less content

Ví dụ:

import { useToggle } from "@uidotdev/usehooks";

export default function App() {
  const [on, toggle] = useToggle(true);

  return (
    <section>
      <h1>Toggle Demo</h1>
      <button disabled={on} onClick={() => toggle(true)}>
        Bật
      </button>
      <button disabled={!on} onClick={() => toggle(false)}>
        Tắt
      </button>
      <button onClick={toggle}>
        Toggle
      </button>
      <div>
        <label>
          <input
            onChange={toggle}
            type="checkbox"
            checked={on}
          />
          <span>Trạng thái: {on ? "Bật" : "Tắt"}</span>
        </label>
      </div>
    </section>
  );
}

5. useIdle - Detect Khi User Không Hoạt Động

Hook này cực kỳ hữu ích cho các tình huống cần biết user có đang active hay không

Use case:

  • Auto logout khi user idle quá lâu (banking/healthcare apps)
  • Pause video khi không xem
  • Tắt animations để tiết kiệm pin
  • Pause background processes
  • Hiển thị screensaver

Ví dụ:

import { useIdle } from "@uidotdev/usehooks";

export default function App() {
  const idle = useIdle(5000); // 5 giây

  return (
    <section>
      <h1>useIdle Demo</h1>
      <div>
        <label>Trạng thái: {idle ? "Idle" : "Active"}</label>
      </div>
      {idle ? (
        <p>Đã 5 giây rồi, di chuyển chuột đi bạn! 🖱️</p>
      ) : (
        <p>Đứng yên và chờ 5 giây xem...</p>
      )}
    </section>
  );
}

6. useMeasure - Đo Kích Thước Element

Hook này giúp anh em đo kích thước của element một cách real-time. Hoàn hảo cho anh em nào có các dự án cần layouts linh hoạt!

Use case:

  • Responsive components
  • Dynamic layouts
  • Show element size feedback
  • Resize handlers

Ví dụ:

import { useMeasure } from "@uidotdev/usehooks";

export default function App() {
  const [firstRef, { width: firstWidth }] = useMeasure();
  const [secondRef, { width: secondWidth }] = useMeasure();

  const lineStyle = (width) => ({
    width: `${width}px`,
    height: "4px",
    backgroundColor: "blue",
    resize: "horizontal",
    overflow: "auto",
    minWidth: "50px",
    maxWidth: "100%",
  });

  return (
    <div>
      <div ref={firstRef} style={lineStyle(250)} />
      <p>Chiều rộng line 1: {Math.floor(firstWidth)}px</p>
      
      <div ref={secondRef} style={lineStyle(150)} />
      <p>Chiều rộng line 2: {Math.floor(secondWidth)}px</p>
    </div>
  );
}

7. useLocalStorage - Sync State Với LocalStorage

Hook này tự động sync state của bạn với localStorage. Quá tiện cho việc persist data!

Use case:

  • Save user preferences
  • Theme settings (dark/light mode)
  • Cache API responses
  • Store auth tokens
  • Save form drafts
  • Remember user inputs

Ví dụ với Theme Preference:

import { useLocalStorage } from "@uidotdev/usehooks";

export default function App() {
  const [theme, setTheme] = useLocalStorage("theme", "light");
  const [username, setUsername] = useLocalStorage("username", "");

  return (
    <section style={{
      backgroundColor: theme === "dark" ? "#1a1a1a" : "#ffffff",
      color: theme === "dark" ? "#ffffff" : "#000000",
      padding: "20px"
    }}>
      <h1>Theme Settings</h1>
      
      <div>
        <label>Username: </label>
        <input
          value={username}
          onChange={(e) => setUsername(e.target.value)}
          placeholder="Nhập tên của bạn"
        />
      </div>

      <div style={{ marginTop: "20px" }}>
        <button onClick={() => setTheme("light")}>
          Light Mode ☀️
        </button>
        <button onClick={() => setTheme("dark")}>
          Dark Mode 🌙
        </button>
      </div>

      <p style={{ marginTop: "20px" }}>
        Xin chào {username || "bạn"}! Theme hiện tại: {theme}
      </p>
      <p style={{ fontSize: "14px", color: "gray" }}>
        💡 Reload trang xem, settings vẫn được lưu!
      </p>
    </section>
  );
}

Đơn giản mà hiệu quả! Data tự động sync với localStorage, reload trang vẫn giữ nguyên! ✨

🎁 Bonus: useCounter - Counter Logic Đơn Giản

Last but not least, một hook classic cho counter với min/max constraints!

Use case:

  • Pagination
  • Step-based forms
  • Rating systems
  • Quantity selectors
  • Inventory management

Ví dụ:

import { useCounter } from "@uidotdev/usehooks";

export default function App() {
  const [count, { increment, decrement, set, reset }] = useCounter(5, {
    min: 5,
    max: 10,
  });

  return (
    <section>
      <h1>Counter với min/max</h1>
      <button disabled={count >= 10} onClick={increment}>
        Tăng
      </button>
      <button disabled={count <= 5} onClick={decrement}>
        Giảm
      </button>
      <button onClick={() => set(6)}>
        Set = 6
      </button>
      <button onClick={reset}>
        Reset
      </button>
      <p>Số đếm: {count}</p>
    </section>
  );
}

Lời nói cuối

Hãy khám phá còn nhiều custom hook khác trong useHooks - một thư viện cực kỳ vip pro và tiện lợi cho React developers. Với những hooks này, anh em có thể code nhanh hơn, code clean hơn, tái sử dụng logic dễ dàng, xong task nhanh hơn, Tập trung vào business logic thay vì **reinvent the wheel ** 😄😄😄

Happy coding! 💻🚀


Nếu thấy hay thì cho mình xin một bookmark ở phía bên trái để bài viết đến được nhiều người hơn nha

Chúng mình có tạo Group cho các bạn cùng chia sẻ và học hỏi về frontend nâng cao, các câu phỏng vấn khó nha 😄😄😄

Các bạn tham gia để gây dựng cộng đồng Frontend Việt Nam thật lớn mạnh nhé 😍😍😍

Cộng Đồng Frontend Nâng Cao Việt Nam: https://www.facebook.com/groups/seniorfrontendvietnam

Kênh TikTok: https://www.tiktok.com/@sydexa.com

Kênh youtube: https://www.youtube.com/@sydexa.official

Nếu thấy hay thì cho mình xin một bookmark ở phía bên trái để bài viết đến được nhiều người hơn nha



All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí