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.

npx create-react-app codersera-hooks-tutorial --template typescript
  # or
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.

Integrating antd in React With Hooks

Add antd as a dependency
yarn add antd

Add ant css to load styling

# src/index.tsx
import 'antd/dist/antd.css';

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.


#src/components/StateHooksComponent.tsx

import React from "react";
interface Props {
}
const StateHooksComponent: React.FC = ({}) => {
    return (
        <div>State Hooks component</div>
    )
}
export default StateHooksComponent;

After this, App.tsx will look like this:

import React from 'react';
import './App.css';
import StateHooksComponent from './components/StateHooksComponent';
const App: React.FC = () => {
  return (
    <div classname="App">
      
    </div>
  );
}
export default App;

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

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

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.


const handleSubmit = (e: FormEvent) => {
        e.preventDefault();
    };
const onNameChange = (e: ChangeEvent) => {
        setName(e.target.value);
};

After making the necessary 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 = ({}) => {
 
    const [name, setName] = useState('');
 
    const handleSubmit = (e: FormEvent) => {
        e.preventDefault();
        console.log(name);
    };
 
    const onNameChange = (e: ChangeEvent) => {
        setName(e.target.value);
    };
 
    return (
        <form layout="&quot;inline&quot;" onsubmit="{handleSubmit}">
            
                
                
            </form.item>
        </form>
    )
}
 
export default StateHooksComponent;

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

react

Using Effects/Lifecycle With Hooks (React.useEffect) useEffect provides the features of componentWillUpdate, componentWillMount, and componentWillUnmount in one function.

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 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.

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

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:


import React, {ChangeEvent, FormEvent, useState, useEffect} from "react";
import {Form, Input, Button} from "antd";
 
interface Props {
}
 
const StateHooksComponent: React.FC = ({}) => {
 
    const [name, setName] = useState('');
    const [address, setAddress] = useState('');
 
    const handleSubmit = (e: FormEvent) => {
        e.preventDefault();
        console.log(name);
    };
 
    const onNameChange = (e: ChangeEvent) => {
        setName(e.target.value);
    };
 
    const onAddressChange = (e: ChangeEvent) => {
        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 (
        
) }; export default StateHooksComponent;

The above code will produce the following output image

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.