blog 3 image

How to create a controlled form component with React-Typescript

6 min read

Prequisite:
JavascriptTypescriptReact
  • 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 event
const [changeValue, setChangeValue] = useState<string>("initial value");

// For the submit event
const [submitValue, setSubmitValue] = useState<string>("");

// When user submit form
const submittedForm = (event: FormEvent<HTMLFormElement>) => {
// Prevent page reloading
event.preventDefault()
// Collects the textarea element
const textarea = event.currentTarget.children[0] as HTMLTextAreaElement; 
// Set the final value
setSubmitValue(textarea.value);
};

//When user types within the textarea
const changeTextarea = (event: ChangeEvent) => {
// Collects the textarea element
const textarea = event.currentTarget as HTMLTextAreaElement;
// Update the textarea element value with the user inputs
setChangeValue(textarea.value);
};

return (
<div>
<form onSubmit={submittedForm}>
<textarea
name="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.