ReactJS – useEffect Hook

Page Content:
1.Introduction
2.Syntax
3.Types of Side Effects

1.Introduction:

1.The Effect Hook allows us to perform side effects (an action) in the function components.
2.Function component doesn’t have life cycle methods which are available in class components ,In other words Effects Hooks are equivalent to componentDidMount(), componentDidUpdate() , and componentWillUnmount() lifecycle methods.


2.Syntax:

 useEffect(()=>{},[]);

where,
()=>{} − Function passed to this hook
[ ] − It tells the hook when to re-render the component.

For example −
[props] − If props values are changed then this hook is called again.
  [ ] − This hook will be called once only when the component is rendered to the screen.


3.Types of Side Effects:

    There are two common side effects in React components: side Effects without cleanup & side Effects with the cleanup.

1.Side Effects without cleanup:

    These side effects have below common features such as,
1.Updating the DOM
2.Fetching and consuming data from a server API  
3.Network requests & logging

    These effects don’t need any cleanup, because we can run them and immediately forget about them.

 Let us understand Hook Effect with the following example.

import React, { useState, useEffect } from 'react';  
  function App() {  
  const [count, setCount] = useState(0);  
 
  // Similar to componentDidMount and componentDidUpdate:  
  useEffect(() => {  
    // Update the document title using the browser API  
    console.log("useEffect called"); 
    document.title = `You clicked ${count} times`;  
  });  
  return (  
    <div>  
      <p>You clicked {count} times</p>  
      <button onClick={() => setCount(count + 1)}>  
        Click me  
      </button>  
    </div>  
  );  
}  
export default App;  

    We declare the count state variable, and then we tell React we need to use an effect. We pass a function to the useEffect Hook. This function we pass is our effect. Inside our effect, we set the document title using the document.title browser API. We can read the latest count inside the effect because it’s in the scope of our function. When React renders our component, it will remember the effect we used, and then run our effect after updating the DOM.

Question: What does useEffect do?
Answer:
1.useEffect tell React that your component needs to do something after render.
2.React will remember the function you passed (we’ll refer to it as our “effect”), and call it later after performing the DOM updates.

Question: Why is useEffect called inside a component?
Answer:
1.Placing useEffect inside the component lets us access the state variable (or any props) right from the effect.
2. We don’t need a special API to read it — it’s already in the function scope.

Question: Does useEffect run after every render?
Answer:

1.Yes! By default, it runs both after the first render and after every update.
2.But we can customize it & You can tell React to skip applying an effect if certain values haven’t changed between re-renders.

Question: Why did we return a function from our effect?
Answer:

This is the optional cleanup mechanism for effects. Every effect may return a function that cleans up after it.

2.Side Effects with cleanup:

     Previously we looked at the effects which don’t need any cleanup for side effects,now lets learn the side effects with the cleanup.

#When to use cleanup?

    There any multiple scenarios such as setting up a subscription to some external data source. In such a case, it is important to clean up so that we don’t introduce a memory leak.

A)Subscription cleanup using the class component:

    In a React class, we set up a subscription in componentDidMount, and clean it up in  componentWillUnmount.
    Here’s how we might subscribe and display that status using a class:
App.js:

import React,{useState,useEffect} from 'react';
import myAPI from './myAPI';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { id:1,isOnline: true };
    this.handleStatusChange = this.handleStatusChange.bind(this);
  }
  componentDidMount() {   
      myAPI.subscribeToStatus(this.state.id);  
      }  
  componentWillUnmount() {    
       myAPI.unsubscribeFromStatus(this.state.id); 
      }  
  handleStatusChange() {    
     this.setState({isOnline:!this.state.isOnline}); 
      }
  render() {
      return (
         <>
         {this.state.isOnline ? 'Online' : 'Offline'}
         <button onClick={this.handleStatusChange}> Change Status</button>
         </>
      );
    }
}
 export default App;

myAPI.js:

class myAPI {

   subscribeToStatus( id){
    console.log("subscribed to the Id---"+id);
   }

   unsubscribeFromStatus(id){
    console.log("un-subscribed the Id---"+id);
    }
}
export default new myAPI();

    Here componentWillUnmount ensures unsubscribing the event & compoentwillmount ensures subscription on each render.

B)Subscription cleanup using function component:

    With hooks adding and removing a subscription is so tightly related that useEffect is designed to keep it together. To run the clean-up at the time of the un-mounting component, we need to return a function from useEffect.

import React,{useState,useEffect} from 'react';
 import myAPI from './myAPI';

function App(){
   var [id,setId]=useState(1);
   var [isOnline,setIsOnline]=useState(true);

   function handleStatusChange() {    
     setIsOnline(isOnline=!isOnline); 
      }

  useEffect(()=>{
     myAPI.subscribeToStatus(id);

     return function cleanup(){
         myAPI.unsubscribeFromStatus(id); 
     }
  });

  return (
     <>
         {isOnline ? 'Online' : 'Offline'}
          <button onClick={handleStatusChange}> Change Status</button>
     </>
  );
}

export default App;

Question: Why did we return a function from our effect?
Answer:
    To run the clean-up at the time of the un-mounting component, we need to return a function from useEffect.

Question: When exactly does React clean up an effect? 
Answer:
1.React performs the cleanup when the component unmounts.
2.React cleans up effects from the current render as well as previous render before running the effects next time.

Note:
    We don’t have to return a named function from the effect instead we could return an arrow function.

useEffect(()=>{
     myAPI.subscribeToStatus(id);
     return ()=>{
         myAPI.unsubscribeFromStatus(id); 
     }
  });

Leave a Reply