Debounce input keyup event in React
This is a follow-up to my previous blog on Using JavaScript Debounce, where I did a detailed explanation on how to use debounce to avoid sending excessive network requests.
Recently, I was working on a personal project using React
and TypeScript
, where I needed to code a registration form. The form included a username
input field, which required sending a POST
request to the server to check if the username already existed in the database. This is how I implemented in React.
./src/routes/register.tsx
import Input from "../components/Input";
import { useState, KeyboardEvent, FormEvent } from "react";
export default function RegisterForm() {
const [isVerifyingUsername, setIsVerifyingUsername] = useState(false);
const [usernameExists, setUsernameExists] = useState(false);
let timeout: ReturnType<typeof setTimeout>;
const debounce = (e: KeyboardEvent<HTMLInputElement>) => {
const input = e.target as HTMLInputElement;
clearTimeout(timeout);
timeout = setTimeout(() => {
// show spinner whenever we're verifying username
setIsVerifyingUsername(true);
verifyUsername(input.value.trim());
}, 500);
};
const verifyUsername = async (username: string) => {
// need to clear out previous error message, if any
setUsernameExists(false);
// communicate with server to check if this username exists
const res = await fetch(`/api/user/${username}`);
if (res.ok) {
// this user exits in database
setUsernameExists(true);
} else {
setUsernameExists(false);
}
setIsVerifyingUsername(false);
};
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
// ...
};
return (
<form onSubmit={handleSubmit}>
<Input
name="username"
labelText="Username"
id="register-username"
placeholder="Your username"
spinner={isVerifyingUsername ? true : false}
onKeyUp={debounce}
errorMessage={
usernameExists ? (
<span className="input-field__error">
Username already exists.
</span>
) : null
}
/>
{/* // ... other form elements */}
</form>
);
}