🚦 Rate Limiting in React Apps
Rate limiting protects your app and backend from abuse by limiting how often a user or client can make requests. While enforcement typically happens on the backend, React apps can implement basic client-side limits as well.
🛡️ 1. Server-Side Is Critical
True protection must be implemented server-side (e.g., via Express middleware like express-rate-limit
or APIs like Cloudflare or Nginx). Client-side limits can reduce load but are not secure alone.
⚙️ 2. Throttling in React
Throttling ensures a function (like an API call) is only triggered at most once every X ms.
import { useCallback } from 'react';
import throttle from 'lodash.throttle';
function SearchBox() {
const handleSearch = useCallback(throttle((query) => {
fetch(`/api/search?q=${query}`);
}, 1000), []);
return (
<input onChange={(e) => handleSearch(e.target.value)} />
);
}
🕒 3. Debouncing in React
Debouncing delays function execution until the user stops typing or interacting.
import { useCallback } from 'react';
import debounce from 'lodash.debounce';
function SearchBox() {
const handleSearch = useCallback(debounce((query) => {
fetch(`/api/search?q=${query}`);
}, 500), []);
return (
<input onChange={(e) => handleSearch(e.target.value)} />
);
}
🚧 4. Handle API Rate Limits
If the API responds with a 429 Too Many Requests
status, you can notify the user or implement retries:
fetch('/api/data')
.then(res => {
if (res.status === 429) {
alert("You're making requests too quickly. Please wait.");
}
return res.json();
});
📋 Summary
- Server-side rate limiting is essential for protection
- Use
throttle
anddebounce
for client-side API call management - Handle
429
errors gracefully - React can reduce redundant traffic, but not block abuse