How to use react useState & useEffect

In this article, I will show you how to use React hooks. React hooks is the newest addition to reactjs framework. There are few of them or you can write your own. React hooks gives more power to functional components. Hooks allows you use sate inside functional components. With react hooks you use state and other react features without creating ES6 classes.

Look at the following code;

import * as  React from 'react';
import * as Reactdom from 'react-dom';
 
const Person=()=>{
    var name:string='John Conner';
    return <React.Fragment>
        <h2>Hello {name}</h2>
        <button type="button"
            onClick={()=>{
                name="Jack Ryan";                
            }}
        >Update Name</button>
    </React.Fragment>    
}
Reactdom.render(<Person/>,document.getElementById("app")); 

When run above code you will see following the screen;

Functional component without state
Functional component without state

We are trying to update the name variable within the button onclick event. Does it work? No it doesn’t. Why it is not working? Even though name variable gets updated with the new value, but there is no state update to tell react virtual DOM to render after updating the variable.  The functional component can’t manage it’s own state. How do we fix this issue? React Hooks can fix this. Let me show you how react hooks can fix this.

How to use React Hooks to manage state within Functional components?

To understand this you need to know a bit about ES6 key value pairs and how it maps key and value into an object. Let’s look at the following code;

 const PersonHook=()=>{
    //How to declare state within the functional component
    //And initialise it's value
    const [name,setName]= React.useState('John Conner') 
 
    return <React.Fragment>
        <h2>Hello My name is {name}</h2>
        <button type="button"
            onClick={()=>{               
            }}
        >Update Name</button>
    </React.Fragment>    
} 

Let me explain this declaration of React Hooks in detail using following code;

 const [name,setName]= React.useState('John Conner')  

Most important part is to remember is it uses Key value pair and React useState Hook. There are two parts in state declaration. First variable name will going to be our state and setName is the callback function that update the name at any given point. In this case useState holds a single string varible. Let me show you how you can use this setName function to update name variable while clicking the button.

 const PersonHook=()=>{
    //How to declare state within the functional component
    //And initialise it's value
    const [name,setName]= React.useState('John Conner') 
 
    return <React.Fragment>
        <h2>Hello My name is {name}</h2>
        <button type="button"
            onClick={()=>{ 
                setName('Jack Ryan');            
            }}
        >Update Name</button>
    </React.Fragment>    
} 

On the above code I have changed the onClick event handler to update state within the functional component using setName callback. Save you code and refresh the page, you will see the initial name value as it is. Now click the update button. There the magic happens now name changed to Jack Ryan. Simply this is a very powerful concept, where we can isolate functional components to handle their own logic without depending on parent components. This concept is know as single responcibility principal. Let me show you a real world scenario and how we can use React Hooks greater extend.

How to  use React Hooks to build forms

Below code is using a ES6 functional component to create a simple form to manage person state.

 const PersonData=()=>{
    const [person,setPersonState]=React.useState({
                                        fullname:'Jack Ryan',
                                        phone:'0478938475',
                                        basicsalary:2345.90})
    return <React.Fragment>
        <h3>Person Form</h3>
        <hr/>
        <table>
            <tbody>
                <tr>
                    <td>Full name</td>
                    <td><input type="text" name={"fullname"} value={person.fullname}/></td>
                </tr>
                <tr>
                    <td>Phone</td>
                    <td><input type="phone" name={"phone"} value={person.phone}/></td>
                </tr>
                <tr>
                    <td>Basic salary</td>
                    <td><input type="number" name={"basicsalary"} value={person.basicsalary}/></td>
                </tr>
            </tbody>
        </table>
    </React.Fragment> 
} 

When you save your code and refresh the browser you will see the following form.

A simple form using React hooks
A web form that uses React Hooks

As you can see we can use React Hook useState to define initial state like the way we did it with ES6 classes. This is an example of using an object with react useState hook.

 const [person,setPersonState]=React.useState({
                                        fullname:'Jack Ryan',
                                        phone:'0478938475',
                                        basicsalary:2345.90}) 

Only difference is we are using key value pair to define the state variable and the function that update the state object. Rest of the jsx code is same as before. Let’s use the setPersonState function to update the person state. Let’s write a common onchange event handler and handle onchange event of all the inputs.

 const PersonData=()=>{
    const [person,setPersonState]=React.useState({
                                        fullname:'Jack Ryan',
                                        phone:'0478938475',
                                        basicsalary:2345.90});
    const handleChange=(e)=>{
        const name=e.target.name;
        const value=e.target.value;
        setPersonState({...person,[name]:value})
    }
    return <React.Fragment>
        <h3>Person Form</h3>
        <hr/>
        <table>
            <tbody>
                <tr>
                    <td>Full name</td>
                    <td><input type="text" 
                               name={"fullname"} 
                               value={person.fullname}
                               onChange={(e)=>{handleChange(e)}}
                               /></td>
                </tr>
                <tr>
                    <td>Phone</td>
                    <td><input type="phone" 
                               name={"phone"} 
                               value={person.phone}
                               onChange={(e)=>{handleChange(e)}}
                               /></td>
                </tr>
                <tr>
                    <td>Basic salary</td>
                    <td><input type="number" 
                               name={"basicsalary"} 
                               value={person.basicsalary}
                               onChange={(e)=>{handleChange(e)}}
                               /></td>
                </tr>
            </tbody>
        </table>
    </React.Fragment> 
} 

Save the code and refresh the page. Everything works fine, but you can’t see how state is getting updated. UseEffect React Hooks will fix this purpose. UseEffect React hook listens to all the changes that useState does. It is something similar to componentDIdMount() and ComponentDidUpdate() life cycle methods in a ES6 class. Let’s add useEffect hook into our code. You can add as follows;

 React.useEffect(()=>{
        console.log(person);
    },[person]) 

UseEffect React Hook accepts 2 parameters. First parameter is the callback function and the other is the state object. I will explain more about useEffect in another post. Now save the code and refresh the browser. Press F12 and open developer console and update each input and you will notice state is getting updated like the way it used to be in ES6 classes setState function.

There are more useful react hooks built in. Will dig into them more with future posts.