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

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
