How to create a controlled form component with React-Typescript
6 min read
Prequisite:
- Should have good knowledge of Javascript, Typescript and React
It is always tricky when creating forms, especially when it is a large form. You have to configure your inputs you want the user to insert but also be able to collect the form values and complete the desired task, such as pass the data to the API server.
In React, it is strongly recommended to use controlled form components. Controlled forms in simple terms is watching and controlling every in's and out's value within the form. Say the user has a simple text box to type in, as they type in character by character, controlled forms takes each one and updates the state simultaneously. However, it does require a bit of a setup. But this is made a bit more complicated by the inclusion of Typescript.
With React-Typescript you are, more often than not, expected to include types and DOM casting, which can be quite daunting and confusing at first (it certainly did for me). But with a bit of know how, it will soon become second nature. For example, collecting input elements within the form when submitted requires using the event
object. But the event
object needs to be typed first, otherwise warnings on your terminal will crop up. So, for submit event
we will need to give it a type of FormEvent<HTMLFormElement>
. The FormEvent
is imported from the React library. But that's just one type of event, there are others.
Besides from event object, we also need to collect the elements, setup the state, reassign the state when user inputs values, etc...
Lets just have a look at a simple controlled form component example with an <textarea> element to see how it is done in full.
import React, { ChangeEvent, FormEvent, useState } from "react";
export default function FormControl() {// For the change eventconst [changeValue, setChangeValue] = useState<string>("initial value");
// For the submit eventconst [submitValue, setSubmitValue] = useState<string>("");
// When user submit formconst submittedForm = (event: FormEvent<HTMLFormElement>) => {// Prevent page reloadingevent.preventDefault()// Collects the textarea elementconst textarea = event.currentTarget.children[0] as HTMLTextAreaElement; // Set the final valuesetSubmitValue(textarea.value);};
//When user types within the textareaconst changeTextarea = (event: ChangeEvent) => {// Collects the textarea elementconst textarea = event.currentTarget as HTMLTextAreaElement;// Update the textarea element value with the user inputssetChangeValue(textarea.value);};
return (<div><form onSubmit={submittedForm}><textareaname="textareaName"value={changeValue}onChange={changeTextarea}/><button type="submit">Submit</button></form>
<div>{submitValue}</div></div>);};
The most significant thing you will notice is how we set the textarea element value but also change the value using the change event handler. By doing this, we record everything the user inserts within the textarea element but also assign the value of the textarea at the same time. This is the main gist of controlled form component.
We only care about the submitValue state value, which will be the final data value. Once you have got the submitted value, you can go ahead and complete the form task.