DEV Community

Cover image for Getting started with Typescript with React Hooks
RiyaNegi
RiyaNegi

Posted on • Updated on

Getting started with Typescript with React Hooks

Typescript is the next big thing in the Front End Development domain and if you are looking to upgrade your skills from a junior to an intermediate frontend developer, then it is a must have skill.
Typescript is a a superscript of javascript, so if you know javascript you are already half way there! What Typescript brings to the table is more error-free code with type checking during run time and a code which can be easily documented.

This article is for developers who already know react and javascript and want to shift to typescript, so I won't be focusing on any react concepts. This is a crash course on understanding the basics of using Typescript with React.
random gif

Index

We will be covering all the topics necessary for understanding the basics of using react with typescript.

  1. Info
  2. Setup
  3. Handling State
  4. Handling Props
  5. Handling Functions
  6. Handling Events

In this article we will be building a simple personal watch list that records the movies you input by taking it's name, rating and review. It looks something like.(It is a little stylised but the underlying code is basic)
App Image

Info

Github repo for the project

Online Demo of the Project

Setup

Let's start with initializing our project! I am naming my project typescript-with-react but you can go with anything you like.
npx create-react-app --template typescript typescript-with-react

Okay now change directory to get into your project folder and proceed usually as you do with any react project.

cd typescript-with-react/
code .
npm start
Enter fullscreen mode Exit fullscreen mode

Your code structure should be looking something like this
COde structure

Notice how the files have .ts or .tsx extension. That denotes that those files are transpiled in typescript.
Okay now let's get into the Typescript nitty gritty!

Handling state

In typescript it's necessary to mention type definitions of all variables and functions and what they return.

  • For handling state in react you need to first create an interface where you mention the data type of the variables.
  • In the example below, we have created an interface called IState (You can name it whatever you like).
  • The interface IState is where we will write our type definition of how we want the state variables to be, which in this case is an array of objects. To denote that we add square bracket after the type definitions. And then while using useState, add <IState["form"]> which denotes that the state should be accepting values in the specified format only(IState format in this case which is taking the object 'form' as input format) State image

We have exported IState so that we can use it in another file later on.
An alternate inline method of adding state would be as follows :

const [counter, setCounter] = useState<{name:string,rate:number,review?:string}[]>([])
Enter fullscreen mode Exit fullscreen mode
  • In our case project, we want review to be an optional field while name of the movie and rating of the movie to be compulsory field.
  • Thus for review we have done review?:string where the question mark denotes the value of review could either be a string or undefined. However for name and rate we have strict type definitions which won't accept anything apart from the assigned type definitions.
  • You can add more than one type definitions to a variable in the following way:
inputValue:number | string | null
Enter fullscreen mode Exit fullscreen mode

Here the variable inputValue can either be a data type of number, string or even a null value
Note: null and undefined are not the same data types.

Handling Props

For handling props in react, both the sending and recieving side of the component should make a clear declaration of the type and number of variables or functions involved.Typescript will give an error if anything is missing either on the sending or receiving side

  • This is the sending side.
<List form={form} />
<Form form={form} setForm={setForm} />
Enter fullscreen mode Exit fullscreen mode

From App.tsx we are sending one object ie. form to List.tsx

  • Let's take a look at the List component's recieving side now.
import { IState as IProps } from "../App"

const List: React.FC<IProps> = ({ form }) => {
...
}
Enter fullscreen mode Exit fullscreen mode
  • List is a react functional component that accepts props. In typescript to show that we addReact.FC<IProps> after the List component declaration.
  • We can import the IState under the alias IProps since we know that the type definitions of the object form are exactly the same as the IState object.
  • We can then destructure form in the parameters and use it in the function component.

In the second example, from App.tsx we are sending one object ie. form and one function ie.setForm to Form.tsx
Let's take a look at the Form component's recieving side now.
Form component

As you can see here in this component as well we imported IState under the alias Props, however we have made some customized changes here.

  • Here we created a new interface called IProps that specifies the type defintion of props incoming since we had to specify the type of setForm.

  • We mention form: Props["form"] which means form should be assigned the type definition of IState which is imported under the alias Props
    And then similarly we will now do it for setForm

Protip : to know the type definitions of something you don't have a clue about, just hover over that element like this and copy the type definitions.

hover image

  • Since we have already declared the type definitions of props as Props["form"], we can cut short the type definition of setForm and write it this way instead
 setForm: React.Dispatch<React.SetStateAction<Props["form"]>>
Enter fullscreen mode Exit fullscreen mode
  • Then simply destructure form and setForm in the parameters of the Form function and use it in the component.

Handling Functions

In react-typescript, you need to mention the type of output that function is giving.

  • Here in this example we have called mapList() function to map through the array of list and give table row as an output, which is a JSX element.

function image

  • To mention the output type of this function, add : JSX.Element[] after the parameters, which denotes that the function is supposed to return an array of JSX elements.
  • An interesting thing to note is that we have written a nested return statement because the first return points towards the mapping function.
  • However we aren't supposed to return the mapping function and thus typescript would give an error if we had only one return statement since we have mentioned our return type as JSX.Element[].
  • We did a nested return statement inside the map function so that it specifically returns a pure JSX element ie. a table row in this case.

Protip: If you aren't sure what the return type is,hover over the function to know it's return type.

Alternatively if a function isn't returning anything, mention it's null return type as :void after parameters in this way :

const randomFunction = (): void => {
...
}
Enter fullscreen mode Exit fullscreen mode

Handling Events

For handling events with react typescript we will take a look at the following DOM events called by the following JSX elements in Form component:

<input className="inputBox" type='text' name="name" value={input.name} onChange={(e) => handleChange(e)} />
Enter fullscreen mode Exit fullscreen mode
<textarea className="inputBox" name="review" value={input.review} onChange={(e) => handleChange(e)}></textarea>
Enter fullscreen mode Exit fullscreen mode

Here the input tag has a DOM property called onChange which calls handleChange when an event is triggered.
For this we create a function which knows that it will be recieving an HTML element in parameters.

 const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>): void => {
        setInput({
            ...input,
            [e.target.name]: e.target.value
        })
    }
Enter fullscreen mode Exit fullscreen mode
  • Here we are declaring that e will either be of type React.ChangeEvent<HTMLInputElement> which is what the input tag will send.
  • And since for the movie review field we are using a textarea tag instead of an input tag the e could also be React.ChangeEvent<HTMLTextAreaElement>.
  • Thus the entire type definition of e can be written as e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>.
  • We need to add :void to specify that this function won't be returning anything.

In the second example we will take a look at the onClick event called by the form submit button.

<button className="button" type="submit" onClick={(e) => handleClick(e)}>Submit</button>
Enter fullscreen mode Exit fullscreen mode
const handleClick = (e: React.MouseEvent<HTMLButtonElement>): void => {
        e.preventDefault();
        if (!input.name || !input.rate) {
            return
        }
        setForm([...form, {
            name: input.name,
            rate: parseInt(input.rate),
            review: input.review
        }])
    }
Enter fullscreen mode Exit fullscreen mode

Similar to handleChange function the handleClick function takes a proper type definition of e which in this case is React.MouseEvent<HTMLButtonElement>.

Conclusion

That's it for this crash course! Hope this gives you a fair enough idea of how to use typescript in react. Keep learning and have a great day!

happy gif

Top comments (20)

Collapse
 
ehsan profile image
Ehsan Azizi • Edited

As a side note using React.FC/React.FunctionComponent types to declare functional React components is discouraged for the reasons mentioned here and here

Collapse
 
riyanegi profile image
RiyaNegi

Will check it out thanks!

Collapse
 
amaben2020 profile image
amaben2020

Great job. How do I get an array value from an array in typescript? It gives me an error whenever I do this? I really want to modify my state based on the values from that array. Thanks.

Collapse
 
riyanegi profile image
RiyaNegi

I found this stackoverflow answer helpful, Do check it out
!Link

Collapse
 
amaben2020 profile image
amaben2020

Thanks for your reply. I later filtered and mapped the array before applying the .length () to extract the numbers of items and sort data in that category programmatically.

Collapse
 
alexandrefuente profile image
alexandrefuente

Awesome article, thanks for share.

Collapse
 
andemosa profile image
Anderson Osayerie

I found this article helpful, I am going to be using typescript more in my react projects

Collapse
 
riyanegi profile image
RiyaNegi

I am glad the article was helpful :)

Collapse
 
ponikar profile image
Ponikar

Nice one!

Collapse
 
riyanegi profile image
RiyaNegi

Thanks! :)

Collapse
 
nihatbabazade_ profile image
Nihat BabazadÉ™

Amazing post!

Collapse
 
shakyapeiris profile image
Shakya Peiris

correction typescript is a superscript of javascript

Collapse
 
riyanegi profile image
RiyaNegi

Aaah right! nice catch thanks!

Collapse
 
whales2333 profile image
whales233

thanks! from rick!

Collapse
 
dhaiwat10 profile image
Dhaiwat Pandya

This is a brilliant article Riya 👌🔥

Collapse
 
riyanegi profile image
RiyaNegi

Thanks!

Collapse
 
swagwik profile image
Sattwik Sahu

Just a small change; Instead of adding an onClick listener on the button, you could add an onSubmit listener to the form

Collapse
 
riyanegi profile image
RiyaNegi

Yes right that's the better option!