Skip to main content

Best Practices for React Forms (Live Playground)

Building user-friendly and accessible forms is an essential aspect of web development. In this tutorial, we'll discuss best practices for building forms in React with sample code and simple explanations.

Use Controlled Components

Controlled components are the preferred method for handling form input in React, as they allow you to manage the form state directly within your component. By using controlled components, you can easily perform validation, manipulate input values, and respond to user interactions.

JavaScript
import React, { useState } from 'react';

function ControlledComponent() {
const [text, setText] = useState('');

const handleChange = event => {
setText(event.target.value);
};

return <input type="text" value={text} onChange={handleChange} />;
}

export default ControlledComponent;

In this example, the text state variable represents the value of the input, and the handleChange function updates the state as the user types.

Live Playground, Try it Yourself

Provide Clear Labels and Error Messages

Ensure that each form input has a clear label and provide helpful error messages to guide users through the form. This not only improves the user experience but also makes your form more accessible.

JavaScript
import React, { useState } from 'react';

function ClearLabels() {
const [email, setEmail] = useState('');
const [error, setError] = useState('');

const handleSubmit = event => {
event.preventDefault();
if (!isValidEmail(email)) {
setError('Please enter a valid email address');
} else {
setError('');
console.log('Submitted:', email);
}
};

const handleChange = event => {
setEmail(event.target.value);
};

return (
<form onSubmit={handleSubmit}>
<label htmlFor="email">Email</label>
<input id="email" type="email" value={email} onChange={handleChange} />
{error && <p className="error">{error}</p>}
<button type="submit">Submit</button>
</form>
);
}

export default ClearLabels;

In this example, we provide a clear label for the email input and display a helpful error message when the email address is not valid.

Live Playground, Try it Yourself

Make Your Form Accessible

Accessibility is an important consideration when building forms. One way to improve accessibility is by using the aria-* attributes to provide additional information about your form elements.

JavaScript
import React, { useState } from 'react';

function AccessibleForm() {
const [password, setPassword] = useState('');
const [error, setError] = useState('');

const handleSubmit = event => {
event.preventDefault();
if (password.length < 8) {
setError('Password must be at least 8 characters long');
} else {
setError('');
console.log('Submitted:', password);
}
};

const handleChange = event => {
setPassword(event.target.value);
};

return (
<form onSubmit={handleSubmit}>
<label htmlFor="password">Password</label>
<input
id="password"
type="password"
value={password}
onChange={handleChange}
aria-invalid={!!error}
aria-describedby="password-error"
/>
{error && (
<p id="password-error" className="error">
{error}
</p>
)}
<button type="submit">Submit</button>
</form>
);
}

export default AccessibleForm;

In this example, we use the aria-invalid attribute to indicate when the password input is invalid, and the aria-describedby attribute to associate the error message with the input.

Live Playground, Try it Yourself

Optimize Performance with Debouncing

Debouncing can help improve the performance of your form, especially when performing expensive operations like real-time validation. Debouncing delays the execution of a function until a specified amount of time has passed since the last time the function was called.

JavaScript
import React, { useState, useEffect } from 'react';

function debounce(fn, delay) {
let timeout;
return (...args) => {
clearTimeout(timeout);
timeout = setTimeout(() => fn(...args), delay);
};
}

function DebouncedValidation() {
const [email, setEmail] = useState('');
const [error, setError] = useState('');

const validateEmail = debounce(email => {
if (!isValidEmail(email)) {
setError('Please enter a valid email address');
} else {
setError('');
}
}, 1000);

const handleChange = event => {
setEmail(event.target.value);
validateEmail(event.target.value);
};

return (
<div>
<input type="email" value={email} onChange={handleChange} />
{error && <p className="error">{error}</p>}
</div>
);
}

export default DebouncedValidation;

In this example, we use a debounce function to delay the validation of the email input, ensuring that the validation only occurs after the user has stopped typing for 500 milliseconds.

Live Playground, Try it Yourself

Conclusion

By following best practices for building forms in React, you can create user-friendly and accessible forms that provide a better user experience. By using controlled components, providing clear labels and error messages, optimizing performance with debouncing, and ensuring accessibility, you can build forms that are easy to use and maintain.