Forms are a crucial part of React web applications. They allow users to enter and upload information directly in components from a login screen to a checkout page. As the majority of React applications are single-page apps or web apps that load one page dynamically displaying new information, you will not send the information to a server directly from the form. You will instead capture and submit or show the information in the form on the client-side using an additional JavaScript file.
React forms are unique because either you can allow the browser to process and collect data through React Change Events, or you can use React to completely manage this feature by setting and modifying its input value directly. React formats are unique because they can be reused. The first approach is an unregulated component because React does not set the value. The second approach is a controlled component, since React updates the inputs actively. usereducer in React will make you understand better about React hooks.
Handling Forms
Form handling is an important part of a wide variety of internet applications and React is one of the best way to handle forms. You have plenty of flexibility to regulate and enforce these controls and there are many ways to accomplish the same.
Adding Forms in React
HTML form components function a little differently than the other DOM components, as form components naturally hold some internal status.
When the user submits the form, the Form is the default HTML form browsing activity for a new page. In react, it works only if you want this behaviour. In most cases, however, it is advisable to have a JavaScript function which handles the form submission and has access to the form's user data. A technique called 'controlled components' is the traditional way to do this.
Controlled Components
A controlled component is bound to a value, and its adjustments will be handled in code by using event-based callbacks. Here, the input form variable is handled by the react itself rather than the DOM. In this case, the mutable state is maintained in the state property and modified using setState().
Controlled components have functions which regulate the data that occurs at each on Change event. This data is subsequently saved in the setState() method and updated. It helps components manage the elements and data of the form easier.
The controlled component is a way you can handle the form input via state. If you are using React Hooks, you can change the form input value by just one way and when the user begins writing some setState or useState characters, this state can be called and you can update it through one event like on Change.
You can use the controlled component when you create:
- Forms validation so that when you type, you always have to know the input value to verify whether it is true or not!
- Disable submission icon, except for valid data in all fields
- If you have a format such as the input for a credit card.
Conditional Rendering
You can create dynamic, highly interactive single-page applications (SPAs). The conditional rendering is one function that enables this.
Conditional rendering is a concept that defines how various user interface markups can be rendered if a condition is true or false. In response, it enables us to make various elements or components dependent on a condition. In the following scenarios this concept is used:
- External API data rendering
- Elements may be shown or hidden
- The functionality of the toggling application
- Permit level implementation
- Authentication and approval management.
Submitting Forms
Our new item has additional features, so we have to add additional fields to accommodate these features. We also need to establish a feature to fire the form and transmit information to the remote collection so that it can also be applied.
To call handleSubmit, we must add it to the onSubmit prop on the form. OnSubmit watches and invokes the features to which we transfer them for the form submits.
handleFormSubmit = (event) => {
console.log(this.state.name)
event.preventDefault();
};
render() {
return (
<form onSubmit={this.handleFormSubmit}>
<label>Name:</label>
<input type="text" value={this.state.name} onChange={this.handleNameChange} />
<button type="submit">Send</button>
</form>
);
}
Multiple Input Fields
It is normal to use an onChange handler to listen to changes in the input elements and save their values to form when building a form using react components. A single onChange handler can be configured to manage several different inputs in the form, in addition to managing just one input.
render() {
const colors = ['Blue', 'Red', 'Green', 'Yellow'];
const sizes = ['Small', 'Medium', 'Large', 'XL', 'XXL', '3XL'];
return (
<form>
<ul>
<li>
<label>Name:</label>
<input name="name" type="text" value={this.state.name} onChange={this.handleChanges} />
</li>
<li>
<label>Observation:</label>
<textarea name="observation" value={this.state.observation} onChange={this.handleChanges} />
</li>
<li>
<label>Desired color:</label>
<select name="color" value={this.state.color} onChange={this.handleChanges}>
{colors.map((color, i) => <option key={i} value={color.toLowerCase()}>{color}</option>)}
</select>
</li>
<li>
<label>T-shirt Size:</label>
{sizes.map((size, i) =>
<label key={i}>
{size}
<input
name="size"
value={size.toUpperCase()}
checked={this.state.size === size.toUpperCase()}
onChange={this.handleChanges}
type="radio" />
</label>
)}
</li>
<li>
<label>
I accept the agreement
<input name="acceptedAgreement" type="checkbox" value={this.state.acceptAgreement} onChange={this.handleChanges} />
</label>
</li>
</ul>
</form>
);
}
Validating Form Input
The form must also be able to accept values so that both a development and an edit flow can be used. Since both forms of validation wish to use the same form component, the State and validation logic shall be lifted to a parent component to carry out the validation.
Example:
<form>
<input name="username" type="text" required />
</form>
We have just added a required input feature. In case an empty and valid field has at least one character, the browser will find this input field invalid. If the input fields are at least invalid, the browser will not allow the user to send the form.
Adding Error Message
To show input error feedback we need to transfer the affected and correct properties to its component as a prop for that particular input. Based on the valid state, we will add the error style. We need to update our component file.
import React from 'react';
const TextInput = props => {
let formControl = "form-control";
if (props.touched && !props.valid) {
formControl = 'form-control control-error';
}
return (
<div className="form-group">
<input type="text" className={formControl} {...props} />
</div>
);
}
export default TextInput;
The textarea Tag
Textarea, which is used to get multi-line feedback from the user, is a popular form control. It’s different from a standard text entry that only allows one-line input. An address field is a clear example of a Textarea use case.
Example:
export default class App extends Component {
state = { bio: '' };
handleBioChange = (e) => {
const bio = e.target.value;
this.setState({ bio });
};
render() {
return (
<form>
<label>Bio:</label>
<textarea value={this.state.bio} onChange={this.handleBioChange} />
</form>
);
}
}
The select Tag
Select in HTML helps us to use the dropdown for choosing among many values. Here we are addressing adjusting selected choices based on a particular dropdown. In React, with the aid of the State it is very simple to achieve. It’s a brief for those who don’t care about state.
render() {
return (
<form>
<label>Desired color:</label>
<select value={this.state.color} onChange={this.handleColorChange}>
<option></option>
<option value="orange">Blue</option>
<option value="red">Red</option>
<option value="green">Green</option>
<option value="yellow">Yellow</option>
</select>
</form>
);
}
The file input Tag
In HTML, the user can upload or manipulate one or more files of the device’s storage via the File API via JavaScript.
<input type="file" />
We generate a component of FileUpload and save the file object. We get the uploaded picture file via event.target, update the component status, and show the picture and information.
Handling Multiple Inputs
You can add a name attribute to each item when you need to handle several managed input items.
function useFormFields<T>(initialValues: T) {
const [formFields, setFormFields] = React.useState<T>(initialValues);
const createChangeHandler = (key: keyof T) => (
e: React.ChangeEvent<HTMLInputElement>,
) => {
const value = e.target.value;
setFormFields((prev: T) => ({ ...prev, [key]: value }));
};
return { formFields, createChangeHandler };
}
export function LoginForm() {
const { formFields, createChangeHandler } = useFormFields({
email: "",
password: "",
});
Controlled Input Null Value
The value change of a controlled component prevents the user from adjusting the input unless you wish to. You can accidentally set the value as undefined or null if you have specified a value, but the input is still editable.
class ControlledInput extends React.Component {
constructor(props) {
super(props);
this.state = { name: '' };
this.handleInput = this.handleInput.bind(this);
}
handleInput(event) {
this.setState({
name: event.target.value
});
}
render() {
return (
<input type="text" value={this.state.name} onChange={this.handleInput} />
);
}
}
Alternatives to Controlled Components
It is often tedious to use controlled components, because for every manner in which your data modifies and pipes the entire input state using a React component, you will need to create an Event Handler.
export function LoginForm() {
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
const formData = new FormData(e.target as HTMLFormElement);
api.login(formData.get('email'), formData.get('password'));
};
return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="email">Email</label>
<input
type="email"
id="email"
name="email"
/>
</div>
<div>
Perhaps you found that in the handleSubmit function we are doing something new. We use an integrated FormData browser API. FormData is a convenient way to get field values from our fields of input!
Creating a Basic Form with JSX
With a single element and a submit button using JSX, you are going to generate an empty form. You will manage the form and transfer the information to another service.
import React from 'react';
import './App.css';
function App() {
return(
<div className="wrapper">
<h1>How About Them Apples</h1>
<form>
<fieldset>
<label>
<p>Name</p>
<input name="name" />
</label>
</fieldset>
<button type="submit">Submit</button>
</form>
</div>
)
}
export default App;
Collecting Form Data Using Uncontrolled Components
In this stage, uncontrolled components will be used to collect form data. An uncontrolled component is a component with no response meaning. You can bind to the onChange event to collect the user feedback instead of setting the data on the component. You can learn how the react handles various types of input and how you construct a reusable feature for collecting form data into a single object as you develop the components.
import React, { useReducer, useState } from 'react';
import './App.css';
const formReducer = (state, event) => {<^>
return {
...state,
[event.name]: event.value
}
}
function App() {
const [formData, setFormData] = useReducer(formReducer, {});
const [submitting, setSubmitting] = useState(false);
const handleSubmit = event => {
event.preventDefault();
setSubmitting(true);
setTimeout(() => {
setSubmitting(false);
}, 3000);
}
const handleChange = event => {
setFormData({
name: event.target.name,
value: event.target.value,
});
}
return(
<div className="wrapper">
<h1>How About Them Apples</h1>
{submitting &&
<div>Submtting Form...</div>
}
<form onSubmit={handleSubmit}>
<fieldset>
<label>
<p>Name</p>
<input name="name" onChange={handleChange}/>
</label>
</fieldset>
<button type="submit">Submit</button>
</form>
</div>
)
}
export default App;
Updating Form Data Using Controlled Components
You’ll set up and update your data dynamically with controlled components in this phase. To set or update the form data, you can add a value prop for each variable. The form data will also be reset on the submit.
...
return(
<div className="wrapper">
<h1>How About Them Apples</h1>
{submitting &&
<div>
You are submitting the following:
<ul>
{Object.entries(formData).map(([name, value]) => (
<li key={name}><strong>{name}</strong>: {value.toString()}</li>
))}
</ul>
</div>
}
<form onSubmit={handleSubmit}>
<fieldset>
<label>
<p>Name</p>
<input name="name" onChange={handleChange} value={formData.name || ''}/>
</label>
</fieldset>
<fieldset>
<label>
<p>Apples</p>
<select name="apple" onChange={handleChange} value={formData.apple || ''}>
<option value="">--Please choose an option--</option>
<option value="fuji">Fuji</option>
<option value="jonathan">Jonathan</option>
<option value="honey-crisp">Honey Crisp</option>
</select>
</label>
<label>
<p>Count</p>
<input type="number" name="count" onChange={handleChange} step="1" value={formData.count || ''}/>
</label>
<label>
<p>Gift Wrap</p>
<input type="checkbox" name="gift-wrap" onChange={handleChange} checked={formData['gift-wrap'] || false}/>
</label>
</fieldset>
<button type="submit">Submit</button>
</form>
</div>
)
}
export default App;
Dynamically Updating Form Properties
You will update the form element properties dynamically in this process. During the submission, you can set the property to previous choices to avoid unintended submissions and disable your form.
Every part is currently static. It does not shift with the shape changing. Forms are complex in many applications. Based on previous data, fields can change, justify and reveal mistakes. Fields may disappear or grow as other components are filled.
Like most React components, the components and attributes can be dynamically defined and re-rendered with changes in data.
Fully-Fledged Solutions
Formik is one of the most common options if you’re looking for a full solution, including validation, monitoring of the fields visited, and submitting a handling form. However, it is based on the same controlled components and state management principles—so it is important to get to know them.
Looking to kickstart your coding journey? Discover the best Python beginner course that will unlock endless possibilities. Don't miss out on this unique opportunity to level up your skills. Join now!
Conclusion
In-depth knowledge of forms is important for rich Web apps. In React, you have different options for forms and elements to be connected and regulated. You can upgrade properties, including the value input elements, dynamically like other components. The best way of simplifying unchecked components is to clean them or trigger them with data, but they may not be appropriate circumstances. You can also change data by using controlled components, but can add another abstraction level which can trigger unintended bugs or re-renders.
Whatever your approach, React allows you to upgrade and adjust your forms dynamically to your application and user requirements.