While you are developing your app in React you have multiple options to develop a form. You can choose the plain vanilla HTML form and that works as is:
However, you would want to have more control on your form submission and events. In that case you will want JavaScript functions to take care of that. For example handleSubmit() for submission handleChange() for change in the text for the text box. You will need to make use of State in React to achieve these and you will need to write ‘Controlled Components’ as you are controlling the value of the element in React.
Example
class ReactForm extends React.Component {
constructor(props) {
super(props);
this.state = {fname: ‘ ‘};
}
handleChange(event) {
this.setState({fname: event.target.value});
}
handleSubmit(event) {
//Submit the form first name data this.state.fname;
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit.bind(this)}>
<label>
First Name:
<input type=“text” value={this.state.fname} onChange={this.handleChange bind(this)} />
</label>
<input type=“submit” value=“Submit” />
</form>
);
}
}
While this works great, I thought of using something else instead of the default forms. The idea was to have more control on the way different components are rendered. I evaluated following forms:
1. Redux-Form: Good for complex forms. Offers a lot of features and at the same time it’s heavy(26K)
2. Formik: As per the documentation, Formik is a small library that helps you with the 3 most annoying parts:
- Getting values in and out of form state
- Validation and error messages
- Handling form submission
3. Final Form:
- Smaller in size (4.6K)
- Framework independent, as it has been written in JavaScript
- Uses Observer pattern, so you can subscribe to different events that you are interested in
- No dependencies
I will focus on Final Form from here on. Documentation can be found here. There are 3 ways that you can get started with React Final Form:
1. Installation:
npm install –save react-final-form final-form
2. Import it to the page
import { Form, Field } from “react-final-form”;
Once the prerequisites are setup fields can be created in 4 different ways:
- Default HTML controls
- Reusable Component
- Using ‘render’ function
- Using ‘render’ function as child
Default HTML control
<Form
onSubmit={onSubmit} //function to fire on Submit
validate={required} //function to validate your inputs
initialValues={{ company: “XYZ”, department: “IT”}} //default values
render={({ handleSubmit, form, submitting, pristine, values }) => (
<form onSubmit={handleSubmit}>
<h2>Default HTML Input control </h2>
<div>
<label for=“fName”>First Name</label>
<Field id=“fName” name=“firstName” component=“input” placeholder=“First Name” /> //using the default ‘input’ control
</div>
</form>
)}
/>
Reusable Component
<Form
onSubmit={onSubmit} //function to fire on Submit
validate={required} //function to validate your inputs
initialValues={{ company: “XYZ”, department: “IT”}} //default values
render={({ handleSubmit, form, submitting, pristine, values }) => (
<form onSubmit={handleSubmit}>
<Field
name=“firstName”
component={Input} //reusable component to be defined
label=“Title”
title=“First Name”
placeholder=“First Name”
/>
</form>
)}
/>
Then you create your ‘Input’ component and create the UI as required.
Input.js
import React from “react”;
const Input = props => {
const { placeholder, label, input, meta } = props;
return (
<div className=“form-group row”>
<label className=“col-md-4”>{label}</label>
<div className=“col-md-7”>
<input
type=“text”
{…input}
placeholder={placeholder}
className=“form-control”
/>
</div>
<div className=“col-md-1”>
{meta.error && meta.touched && (
<span className=“text-danger”>{meta.error}</span>
)}
</div>
</div>
);
};
export default Input;
Using ‘render’ function
<div className=“form-group row”>
<Field
name=“desc”
render={({ input, meta }) => ( //using render function
<div>
<label>Description</label>
<textarea {…input} />
{meta.touched && meta.error && <span>{meta.error}</span>}
</div>
)}
/>
</div>
Using ‘render’ function as child
<Field
name=“description”
placeholder=“Please provide description”
validate={required}
>
{(
{ input, meta, placeholder } //destructuring of fieldstate which has 3 keys in it
) => (
<div className=“form-group row”>
<label className=“col-md-4”>Description</label>
<div className=“col-md-7”>
<textarea
type=“text”
{…input}
placeholder={placeholder}
className=“form-control”
/>
</div>
<div className=“col-md-1”>
{meta.error && meta.touched && (
<span className=“text-danger”>{meta.error}</span>
)}
</div>
</div>
)}
</Field>
If you liked the article, share it with your friends and colleagues. You can also send a “Thank you” note by buying me a coffee. Buy Me a Coffee
Great content! Super high-quality! Keep it up! 🙂
I love the content on your websites. Thanks for your time!
You are most welcome!