{{announcement.body}}
{{announcement.title}}

React Hooks With Typescript: Use State and Effect in 2020

DZone 's Guide to

React Hooks With Typescript: Use State and Effect in 2020

In this article, we discuss how to use React Hooks with TypeScript to create functional components with the same features of class-based components.

· Web Dev Zone ·
Free Resource

In this article. we are going to see how functional segments can be used with React hooks to reduce the length of code used in writing class-based components, while still obtaining all their features.

We are going to use TypeScript for this tutorial so that our code remains 100% typesafe, and I must say, if you are doing a big project, Typescript is a must feature one should go with to help keep code clean.

Shell
xxxxxxxxxx
1
 
1
npx create-react-app codersera-hooks-tutorial --template typescript
2
  # or
3
yarn create react-app codersera-hooks-tutorial --template typescript


The above command will generate a project named "codersera-hooks-tutorial". Once it is finished, go to the directory and either npm start or yarn start will give the push to the project.

We will be using yarn throughout this tutorial to maintain uniformity.

Now, we're going to integrate antd ( a design library by the name of ant design), which we will be using to have some standard UI components. (Note, this does not have anything to do with hooks or React in general.)

You may also like: Thinking in React Hooks: Building an App With Embedded Analytics.

Integrating antd in React With Hooks

Add antd as a dependency

TypeScript
xxxxxxxxxx
1
 
1
yarn add antd


Add antd CSS to load stylings.
TypeScript
xxxxxxxxxx
1
 
1
# src/index.tsx
2
 
3
....
4
import 'antd/dist/antd.css';
5
.....


After this, we now have a full TypeScript setup from React with the antd design library integrated.

Using State With Hooks in React (React.useState)

Let us see how to work with hooks. For this, we are going to make a single form segment that will show its value in the input field after submitting the form.

Create a StateHooksComponent.tsx file inside the src/components directory (Create the directory folder if it's not already there.)

Now create a function, StateHooksComponent and import the component in the App.tsx file.   

TypeScript
xxxxxxxxxx
1
16
 
1
#src/components/StateHooksComponent.tsx
2
 
3
import React from "react";
4
interface Props {
5
}
6
 
7
const StateHooksComponent: React.FC<Props> = ({}) => {
8
 
9
    return (
10
        <div>
11
            State Hooks component
12
        </div>
13
    )
14
}
15
 
16
export default StateHooksComponent;


After this, App.tsx will look like this:

TypeScript
xxxxxxxxxx
1
13
 
1
import React from 'react';
2
import './App.css';
3
import StateHooksComponent from './components/StateHooksComponent';
4
 
5
const App: React.FC = () => {
6
  return (
7
    <div className="App">
8
      <StateHooksComponent/>
9
    </div>
10
  );
11
}
12
 
13
export default App;


Now, let's add a button, input field, and output view in our StateHooksComponents.

TypeScript
xxxxxxxxxx
1
 
1
const [name, setName] = useState<string>('');


The useState function will return two things, the state variable, and a dispatcher to set the state. We can apply any naming form, but it's clear to use the following syntax:

[xxx, setXxx]

The handler is designated with an arrow function. For example, there are two handlers: handleSubmit and onChangeEvent.

TypeScript
xxxxxxxxxx
1
 
1
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
2
        e.preventDefault();
3
    };
4
 
5
    const onNameChange = (e: ChangeEvent<HTMLInputElement>) => {
6
        setName(e.target.value);
7
    };


After making the necessary edits, your component will look something like this:

TypeScript




xxxxxxxxxx
1
30


 
1
import React, {ChangeEvent, FormEvent, useState} from "react";
2
import {Form, Input, Button} from "antd";
3
 
4
interface Props {
5
}
6
 
7
const StateHooksComponent: React.FC<Props> = ({}) => {
8
 
9
    const [name, setName] = useState<string>('');
10
 
11
    const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
12
        e.preventDefault();
13
        console.log(name);
14
    };
15
 
16
    const onNameChange = (e: ChangeEvent<HTMLInputElement>) => {
17
        setName(e.target.value);
18
    };
19
 
20
    return (
21
        <Form layout="inline" onSubmit={handleSubmit}>
22
            <Form.Item>
23
                <Input type="text" placeholder="name" value={name} onChange={onNameChange} />
24
                <Button htmlType="submit" type="primary"> Submit </Button>
25
            </Form.Item>
26
        </Form>
27
    )
28
}
29
 
30
export default StateHooksComponent;



Here is the output you should expect after writing some content in the box and clicking on the boxExample output

Example output

Using Effects/Lifecycle With Hooks (React.useEffect)

useEffect provides the features of componentWillUpdate, componentWillMount, and componentWillUnmount in one function.

TypeScript




xxxxxxxxxx
1


 
1
 useEffect(() => {
2
        console.log('Component mounted');
3
        return () => {
4
            console.log('Component will be unmount')
5
        }
6
    }, []); # notice the empty array here, this is optional



Now, the above code is an example of generic useEffect, notice the empty array above. There are three ways in which the useEffect can be used:

  • If the array is empty, the function will be executed once during the mounting of the segments, and the return function will be executed during unmounting. For example, this can be used to initiate API calls to fetch data that needs to be shown on the UI.
  • If no array is provided, the function will be executed before and after each render. This is used to record the number of times rendering is taking place.
  • If there is any state variable inside the array, then the function is executed once on the mounting of the component, and then each time the state is changed, the function is called.
TypeScript




xxxxxxxxxx
1
10


 
1
.......
2
const [name, setName] = useState<string>('');
3
const [options, setOptions] = useState<Array<string>>([]);
4
useEffect(()=> {
5
 if(name){
6
 // fetch auto suggest options from backend, 
7
 setOptions(data);
8
 }
9
}, [name])
10
..........



Now, each time the user types any character in the input field, which is assigned to auto-suggest options, data will be fetched from the server and updated to options state, which can be used to show the auto-suggest options.

Below is the code block to show how the use effect will be called:

TypeScript




xxxxxxxxxx
1
51


 
1
import React, {ChangeEvent, FormEvent, useState, useEffect} from "react";
2
import {Form, Input, Button} from "antd";
3
 
4
interface Props {
5
}
6
 
7
const StateHooksComponent: React.FC<Props> = ({}) => {
8
 
9
    const [name, setName] = useState<string>('');
10
    const [address, setAddress] = useState<string>('');
11
 
12
    const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
13
        e.preventDefault();
14
        console.log(name);
15
    };
16
 
17
    const onNameChange = (e: ChangeEvent<HTMLInputElement>) => {
18
        setName(e.target.value);
19
    };
20
 
21
    const onAddressChange = (e: ChangeEvent<HTMLInputElement>) => {
22
        setAddress(e.target.value);
23
    };
24
 
25
    useEffect(() => {
26
        console.log('Component mounted');
27
        return () => {
28
            console.log('Component will be unmount');
29
        }
30
    }, []);
31
 
32
    useEffect(() => {
33
        console.log(`Any state changed Name: ${name}, Address: ${address}`);
34
    });
35
 
36
    useEffect(() => {
37
        console.log(`Name changed: ${name}`);
38
    }, [name]);
39
 
40
    return (
41
        <Form layout="inline" onSubmit={handleSubmit}>
42
            <Form.Item>
43
                <Input type="text" placeholder="name" value={name} onChange={onNameChange}/>
44
                <Input type="text" placeholder="address" value={address} onChange={onAddressChange} />
45
                <Button htmlType="submit" type="primary"> Submit </Button>
46
            </Form.Item>
47
        </Form>
48
    )
49
};
50
 
51
export default StateHooksComponent;



The above code will produce the following output image

Example autofill output

Example autofill output

So, this is how you can use functional components  instead of class-based components and still use all the features that you were able to do with class lifecycle methods.


Further Reading

Topics:
react ,typescript ,hooks

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}