react-use-debounce-hook
Version:
A lightweight React hook for debouncing values with zero dependencies.
251 lines (193 loc) • 5.87 kB
Markdown
# react-use-debounce-hook
A lightweight React hook for debouncing values with no external dependencies.
## 📦 Install
```bash
npm install react-use-debounce-hook
```
```bash
yarn add react-use-debounce-hook
```
```bash
pnpm add react-use-debounce-hook
```
## 🚀 Quick Start
```tsx
import { useDebounce } from "react-use-debounce-hook";
const Component = () => {
const [text, setText] = useState("");
const debouncedText = useDebounce(text, 500);
useEffect(() => {
if (debouncedText) {
console.log("Debounced value:", debouncedText);
}
}, [debouncedText]);
return <input value={text} onChange={(e) => setText(e.target.value)} />;
};
```
## 📖 API Reference
### `useDebounce<T>(value: T, delay: number): T`
A React hook that returns a debounced version of the input value.
#### Parameters
- **`value`** (`T`): The value to debounce. Can be any type (string, number, object, etc.)
- **`delay`** (`number`): The delay in milliseconds before updating the debounced value
#### Returns
- **`T`**: The debounced value of the same type as the input
## 💡 Usage Examples
### Basic Text Input Debouncing
```tsx
import React, { useState, useEffect } from "react";
import { useDebounce } from "react-use-debounce-hook";
function SearchComponent() {
const [searchTerm, setSearchTerm] = useState("");
const debouncedSearchTerm = useDebounce(searchTerm, 300);
useEffect(() => {
if (debouncedSearchTerm) {
// Perform search API call
searchAPI(debouncedSearchTerm);
}
}, [debouncedSearchTerm]);
return (
<input
type="text"
placeholder="Search..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
);
}
```
### Debouncing Form Values
```tsx
import React, { useState, useEffect } from "react";
import { useDebounce } from "react-use-debounce-hook";
function FormComponent() {
const [formData, setFormData] = useState({
name: "",
email: "",
message: "",
});
const debouncedFormData = useDebounce(formData, 1000);
useEffect(() => {
// Auto-save form data
if (debouncedFormData.name || debouncedFormData.email) {
saveFormData(debouncedFormData);
}
}, [debouncedFormData]);
const handleChange = (field: string, value: string) => {
setFormData((prev) => ({ ...prev, [field]: value }));
};
return (
<form>
<input
type="text"
placeholder="Name"
value={formData.name}
onChange={(e) => handleChange("name", e.target.value)}
/>
<input
type="email"
placeholder="Email"
value={formData.email}
onChange={(e) => handleChange("email", e.target.value)}
/>
<textarea
placeholder="Message"
value={formData.message}
onChange={(e) => handleChange("message", e.target.value)}
/>
</form>
);
}
```
### Debouncing API Calls
```tsx
import React, { useState, useEffect } from "react";
import { useDebounce } from "react-use-debounce-hook";
function UserSearch() {
const [query, setQuery] = useState("");
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(false);
const debouncedQuery = useDebounce(query, 500);
useEffect(() => {
if (debouncedQuery) {
setLoading(true);
fetchUsers(debouncedQuery)
.then(setUsers)
.finally(() => setLoading(false));
} else {
setUsers([]);
}
}, [debouncedQuery]);
return (
<div>
<input
type="text"
placeholder="Search users..."
value={query}
onChange={(e) => setQuery(e.target.value)}
/>
{loading && <div>Loading...</div>}
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</div>
);
}
```
### Debouncing Window Resize
```tsx
import React, { useState, useEffect } from "react";
import { useDebounce } from "react-use-debounce-hook";
function ResponsiveComponent() {
const [windowSize, setWindowSize] = useState({
width: window.innerWidth,
height: window.innerHeight,
});
const debouncedWindowSize = useDebounce(windowSize, 250);
useEffect(() => {
const handleResize = () => {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight,
});
};
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
useEffect(() => {
// Handle debounced window size changes
console.log("Window size changed:", debouncedWindowSize);
}, [debouncedWindowSize]);
return (
<div>
<p>
Window size: {debouncedWindowSize.width} x {debouncedWindowSize.height}
</p>
</div>
);
}
```
## 🔧 TypeScript Support
This package is written in TypeScript and provides full type safety:
```tsx
import { useDebounce } from "react-use-debounce-hook";
// TypeScript will infer the correct types
const [user, setUser] = useState<User | null>(null);
const debouncedUser = useDebounce(user, 1000); // Type: User | null
const [numbers, setNumbers] = useState<number[]>([]);
const debouncedNumbers = useDebounce(numbers, 500); // Type: number[]
```
## ⚡ Performance
- **Zero dependencies**: No external dependencies, keeping your bundle size minimal
- **Memory efficient**: Properly cleans up timeouts to prevent memory leaks
- **Type-safe**: Full TypeScript support with generic types
- **React 18+ compatible**: Works with the latest React features
## 🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## 📄 License
MIT © [Syed Junaid](https://github.com/syedjunaid92)
## 🔗 Related
- [React](https://reactjs.org/) - A JavaScript library for building user interfaces
- [TypeScript](https://www.typescriptlang.org/) - Typed JavaScript