React Hooks with Typescript: Use State and Use Effect in 2020.

In this blog, we are going to see how functional components can be used with react hooks to reduce the amount of code used in writing class-based components and still achieving all the features of it.

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


npx create-react-app codersera-hooks-tutorial --template typescript
  # or
yarn create react-app codersera-hooks-tutorial --template typescript

The above command will create a project with the name codersera-hooks-tutorial. Once it is done, go straight to the directory and either npm start or yarn start, will kickstart the project.

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

Let us now integrate antd ( a design library by the name of ant design), which we will be using to have some standard UI components. And, this does not have to do anything with hooks or react in general.

Integrating antd in react with hooks

  • Add antd to dependency

yarn add antd
  • Add antd css to load stylings
# src/index.tsx

....
import 'antd/dist/antd.css';
.....

That’s all, we now have a complete typescript setup off react with antd design library integrated.

Using State with hooks in React (React.useState)

Let us see how the state is used with hooks. For this, we are going to create a simple form component, that will show the value in the input field upon submitting the form.

  • Create a StateHooksComponent.tsx file inside src/components directory, create the directory if not already there.
  • Now create a function StateHooksComponent and import the component in App.tsx file.
#src/components/StateHooksComponent.tsx

import React from "react";
interface Props {
}

const StateHooksComponent: React.FC<Props> = ({}) => {

    return (
        <div>
            State Hooks component
        </div>
    )
}

export default StateHooksComponent;

After this, your App.tsx file would look like:


import React from 'react';
import './App.css';
import StateHooksComponent from './components/StateHooksComponent';

const App: React.FC = () => {
  return (
    <div className="App">
      <StateHooksComponent/>
    </div>
  );
}

export default App;

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


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

The useState will return 2 things, one is the state variable, and the other is the dispatcher to set this state. We can use any naming convention, but it’s obvious to use the following syntax :

[xxx, setXxx]

The handler is assigned with an arrow function. For instance, there are two handlers for handlingSubmit and handling onChangeEvent.


    const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
        e.preventDefault();
    };

    const onNameChange = (e: ChangeEvent<HTMLInputElement>) => {
        setName(e.target.value);
    };

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


import React, {ChangeEvent, FormEvent, useState} from "react";
import {Form, Input, Button} from "antd";

interface Props {
}

const StateHooksComponent: React.FC<Props> = ({}) => {

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

    const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        console.log(name);
    };

    const onNameChange = (e: ChangeEvent<HTMLInputElement>) => {
        setName(e.target.value);
    };

    return (
        <Form layout="inline" onSubmit={handleSubmit}>
            <Form.Item>
                <Input type="text" placeholder="name" value={name} onChange={onNameChange} />
                <Button htmlType="submit" type="primary"> Submit </Button>
            </Form.Item>
        </Form>
    )
}

export default StateHooksComponent;

And here is the output that you should expect after typing some content in the box and clicking on submit button.

Using Effects/Lifecycle with Hooks (React.useEffect)

useEffect basically provides the features of componentWillUpdate, componentWillMount, componentWillUnMount all in one.


    useEffect(() => {
        console.log('Component mounted');
        return () => {
            console.log('Component will be unmount')
        }
    }, []); # 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 3 ways in which the useEffect can be used.

  • If the array is empty, the function will get executed once during the mounting of the component, 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 on before and after each render, this is used to record how many times rendering is taking place.
  • If there is any state variable inside the array, then the effects function is executed once on the mounting of the component, and then each time the state is changed, the function is called. A very useful example of this property is, suppose you want to show an autosuggest options, let’s say user is typing in an input field and based on the initial text you want to show him auto-suggested words/sentence, then you can use this property to fetch the data from backend each time the input value is changing.


.......
const [name, setName] = useState<string>('');
const [options, setOptions] = useState<Array<string>>([]);
useEffect(()=> {
	if(name){
		// fetch auto suggest options from backend, 
		setOptions(data);
	}
}, [name])
..........

Now each time user type any character in the input field, which is assigned to name, auto-suggest 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 :


import React, {ChangeEvent, FormEvent, useState, useEffect} from "react";
import {Form, Input, Button} from "antd";

interface Props {
}

const StateHooksComponent: React.FC<Props> = ({}) => {

    const [name, setName] = useState<string>('');
    const [address, setAddress] = useState<string>('');

    const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        console.log(name);
    };

    const onNameChange = (e: ChangeEvent<HTMLInputElement>) => {
        setName(e.target.value);
    };

    const onAddressChange = (e: ChangeEvent<HTMLInputElement>) => {
        setAddress(e.target.value);
    };

    useEffect(() => {
        console.log('Component mounted');
        return () => {
            console.log('Component will be unmount');
        }
    }, []);

    useEffect(() => {
        console.log(`Any state changed Name: ${name}, Address: ${address}`);
    });

    useEffect(() => {
        console.log(`Name changed: ${name}`);
    }, [name]);

    return (
        <Form layout="inline" onSubmit={handleSubmit}>
            <Form.Item>
                <Input type="text" placeholder="name" value={name} onChange={onNameChange}/>
                <Input type="text" placeholder="address" value={address} onChange={onAddressChange} />
                <Button htmlType="submit" type="primary"> Submit </Button>
            </Form.Item>
        </Form>
    )
};

export default StateHooksComponent;

NOTE: Never change the state of the variable in 2, and never change the state of the variable you are watching in case 3 inside effect function, otherwise use effects will create an endless loop.

The above code will produce the following output:

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

Part 2: How to use React-Redux with redux hooks in typescript.

What is useState hook?

With the help of the useState hook, we can create the state inside the functional component as we used in the class-based components.

What does useState return?

useState return two things, one is state variable and other is dispatcher, using which we can change or update the state variable.

What is useEffect hook?

It provides the class-based life cycle functionality inside the function-based component. We can use componentDidMount, componentDidUpdate and componentWillUnMount inside the function-based component.

Can I use hooks inside the class-based component?

No, you can’t use hooks inside the class component but you can use class component with functional component( which using hooks inside) together.

What does useEffect return?

useEffect returns a function that will be executed when the component will unmount.

Can I use useState or useEffect more than once in a same component?

Yes, you can use useState or useEffect as many times as you need in the same component.

What does useEffect takes in arguments?

It takes two arguments one is, a function and the other is, an array of dependency.

1 thought on “React Hooks with Typescript: Use State and Use Effect in 2020.”

Leave a Comment

Your email address will not be published. Required fields are marked *