When do you validate the value entered by the user in the input form? 🤔
Perhaps, you check it at real timing, or just after tapping a button like "Submit" .
I suggest new way of form validation which uses requestIdleCallback
.
https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback
By checking the data entered by the user while the browser is idle, the result of the validation is already available when the user taps a button like "Confirm" .
It makes us faster response to button taps.
This article introduces the example using idle-task
(v3.3.1) which wraps requestIdleCallback
conveniently.
Example of React
This is the example of react hooks.
import { useRef, useEffect } from "react";
import { setIdleTask, forceRunIdleTask, cancelIdleTask } from "idle-task";
export default function useValidateWhenIdle(
input: string,
validate: (input: string) => boolean
) {
const idleTaskIdRef = useRef(NaN);
useEffect(() => {
const validateTask = () => validate(input);
idleTaskIdRef.current = setIdleTask(validateTask);
return () => {
cancelIdleTask(idleTaskIdRef.current);
};
}, [input, validate]);
return () => forceRunIdleTask(idleTaskIdRef.current);
}
The component that uses this hooks is as follows.
import "./styles.css";
import useValidateWhenIdle from "./useValidateWhenIdle";
import { useState, ChangeEventHandler, FormEventHandler } from "react";
import { configureIdleTask } from "idle-task";
configureIdleTask({
debug: true
});
const validateUserName = (userName: string): boolean => {
return /^[a-zA-Z]+$/.test(userName);
};
export default function App() {
const [userName, setUserName] = useState("");
const validateUserNameWhenIdle = useValidateWhenIdle(userName, validateUserName);
const handleUserNameChange: ChangeEventHandler<HTMLInputElement> = ({
target
}) => {
setUserName(target.value);
};
const handleSubmit: FormEventHandler<HTMLFormElement> = async (event) => {
event.preventDefault();
const isValid = await validateUserNameWhenIdle();
if (isValid) {
alert(`YourName: ${userName}`);
} else {
alert(`${userName} is invalid`);
}
};
return (
<form onSubmit={handleSubmit}>
<label>
FirstName:
<input type="text" value={userName} onChange={handleUserNameChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
First, let's take a closer look at the useValidateWhenIdle
hooks.
useValidateWhenIdle
takes two arguments.
-
input
: String to be validated -
validate
: Function that takes a string to be validated and validates it
The return value is the function which can get validation result.
We will also take a closer look at the internal processing.
const idleTaskIdRef = useRef(NaN);
useEffect(() => {
const validateTask = () => validate(input);
idleTaskIdRef.current = setIdleTask(validateTask);
return () => {
cancelIdleTask(idleTaskIdRef.current);
};
}, [input, validate]);
The setIdleTask
of idle-task
makes the argument function run while the browser is idle.
setIdleTask(validateTask)
will cause validateTask
, a function that validates user input values, to be executed while the browser is idle.
The return value of setIdleTask
is an ID.
This ID can be used to cancel the execution of an idle function or to retrieve the result of an idle function.
We uses useRef
to keep track of the ID.
Then, useEffect
makes us ensure that validation is performed while the browser is idle each time a user-entered value is changed.
In the useEffect
cleanup function, we use cancelIdleTask
to cancel the target process if it has not yet been executed.
return () => forceRunIdleTask(idleTaskIdRef.current);
The result of a function registered with setIdleTask
can be retrieved with forceRunIdleTask
.
If the function has already been executed while the browser is idle, the result is returned; if it has not yet been executed, it is executed immediately.
Next, let's take a closer look at the components on the side that use useValidateWhenIdle
hooks.
import "./styles.css";
import useValidateWhenIdle from "./useValidateWhenIdle";
import { useState, ChangeEventHandler, FormEventHandler } from "react";
import { configureIdleTask } from "idle-task";
configureIdleTask({
debug: true
});
const validateUserName = (userName: string): boolean => {
return /^[a-zA-Z]+$/.test(userName);
};
export default function App() {
const [userName, setUserName] = useState("");
const validateUserNameWhenIdle = useValidateWhenIdle(userName, validateUserName);
const handleUserNameChange: ChangeEventHandler<HTMLInputElement> = ({
target
}) => {
setUserName(target.value);
};
const handleSubmit: FormEventHandler<HTMLFormElement> = async (event) => {
event.preventDefault();
const isValid = await validateUserNameWhenIdle();
if (isValid) {
alert(`YourName: ${userName}`);
} else {
alert(`${userName} is invalid`);
}
};
return (
<form onSubmit={handleSubmit}>
<label>
FirstName:
<input type="text" value={userName} onChange={handleUserNameChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
This is an example of a basic React form implementation.
What are the key points?
const validateUserNameWhenIdle = useValidateWhenIdle(userName, validateUserName);
The useValidateWhenIdle
appears.
The first argument is a string to be validated, and the second argument is a function that defines the validation logic.
And the return value is function which can get the result of
the validation.
It is used when the Submit button is pressed as follows.
const handleSubmit: FormEventHandler<HTMLFormElement> = async (event) => {
event.preventDefault();
const isValid = await validateUserNameWhenIdle();
if (isValid) {
alert(`YourName: ${userName}`);
} else {
alert(`${userName} is invalid`);
}
};
When the Submit button is pressed, we get the validation result by using async/await
.
The page implemented with the code introduced so far can be viewed at the following URL.
Let's see if the validation actually takes place while the browser is idle!
By adding the following code, the results of the validation function execution will be output to the browser's console.
import { configureIdleTask } from "idle-task";
configureIdleTask({
debug: true
});
If you put text in the input area, you will see that validation is taking place during idle.
Measurements taken from the Performance tab of the Chrome Developer Tools show that functions are running while the browser is idle.
You can see the example in CodeSandbox.
Conclusion
I introduced how to validate form during browser idle by using idle-task
.
https://github.com/hiroki0525/idle-task
This article will also help you to optimize your website.
https://dev.to/nuko_suke/improve-responsiveness-to-user-interactions-4a3p
If you found this helpful, please help someone else by sharing it or tagging someone in the comments!
Thanks!
Top comments (1)
Hey, that was a nice read, you got my follow, keep writing 😉