useEffect: Background and what makes it special

useEffect: Background and what makes it special

In this blog, I will show you why and how useEffect hook is much more powerful than we think and how it makes our life so much easier than before

useEffect a brief introduction

What is useEffect?

Well, there are multiple definitions.

According to the Reactjs docs

React beta docs

Well I like to think of useEffect as a react hook which helps us deal with side effects. (anything that is outside of the function API calls, network requests, etc)

Syntax

import React,{useEffect} from "react";

function App() {

useEffect(() => {
  //Async function

  return () => {
    //cleanUp
  }
}, [//Depencency Array])

We write or call our functions inside the hook, and in the dependency array we add the components and props we want to keep an eye for every change to call the hook again, and we sometimes use a return function to clean up for subscriptions we might have made from the useEffect hook

Note: useEffect is called after we’ve rendered our components and the JSX on the DOM.

useEffect anatomy and what makes it powerful.

From seeing the syntax above and the brief explanation, we can see that the useEffect hook does a lot

  1. Runs the async function after the JSX is rendered

  2. Keeps an eye on changes of props and state in dependencies

  3. Does the cleanup

These 3 tasks were done by 3 separate functions in class-based components before useEffect was introduce

componentDidMount () was a function that renders after our JSX is on the screen and

componentDidUpdate() was a function that runs on every update of props and state change

componentWillUnmount() was used to do the cleanup JUST before our component was about to unmount from the DOM

useEffect replaces 3 functions that were needed in class components. POWERFUL

How useEffect makes our life easier

Not only useEffect is powerful and does the work of 3 separate functions at once but it also makes our life easier by removing a lot of code and complexity in our project

Without useEffect

import React from "react";

class Profile extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      userInfo: {},
    };
  }

  async componentDidMount() {
    console.log("Profile - componentDidMount");

    const data = await fetch(`https://api.github.com/users/BhaveshSSingh`);
    const json = await data.json();
    console.log(json);
    this.setState({
      userInfo: json,
    });
  }

componentDidUpdate(prevProps, prevState) {
    if (prevProps.company != this.props.company) {
   // do something
    }
  }

  render() {

    const { login, blog, avatar_url } = this.state.userInfo;
    return (
      <>
        <img src={avatar_url} alt="" />
        <div>Name: {this.props.name}</div>
        <div>UserName: {login}</div>
        <div>Blog: {blog}</div>
      </>
    );
  }
}

export default Profile;

with useEffect

import { useState, useEffect } from "react";

const Profile = (company) => {
  const [userInfo, setUserInfo] = useState("");

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

  async function profileInfo() {
    const data = await fetch(`https://api.github.com/users/BhaveshSSingh`);
    const json = await data.json();
    setUserInfo(json);
  }

  return (
    <>
      <img src={userInfo.avatar_url} alt="" />
      <div>Name: {userInfo.name}</div>
      <div>UserName: {userInfo.login}</div>
      <div>Blog: {userInfo.blog}</div>
    </>
  );
};

Granted the useState and the lesser code of the functional component compared to class components are also at play here,

but we can see how just writing one word in the dependency array can reduce an entire if-else condition. making our code much cleaner, more readable, and reducing complexity.

Conclusion

useEffect is super helpful and superpowerful it replaces 3 functions that were necessary before for writing react code, and it makes the dev experience much much better than before!