DEV Community

Jorjis Hasan
Jorjis Hasan

Posted on • Updated on

Evolution of useEffect in React 🚀

Full Code

Highlights: This project will briefly explain how we used to write the useEffect() functionality in the past and how it has evolved with the changes in react.

Project: The project has two functionalities: count and image. Clicking the render button generates a new image and updates the count.

A preview of the project we will develop:

A preview of the project

Features:

  • Update and render state variables
  • Legacy implementation
  • Bridge data fetch and state variables
  • Gain asynchronous behavior while fetching

I will now implement those features both in the Functional and classBase components.

Functional Component

import { useEffect, useState } from "react";
import { UNSPLASH_API, randomNum } from "../utils";

const RandomImage = () => {
  const [imgUrl, setImgUrl] = useState("");
  const [count, setCount] = useState(0);

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

  const getData = async () => {
    const response = await fetch(UNSPLASH_API);
    const data = await response.json();
    setImgUrl(data[randomNum(0, 10)]?.urls?.small);
  };

  return (
    <div className="container">
      <div className="count">
        <h1>Total Renders →</h1>
        <h2>{count}</h2>
        <button className="btn" onClick={() => setCount(count + 1)}>
          Render ✦
        </button>
      </div>
      <img src={imgUrl} />
    </div>
  );
};

export default RandomImage;
Enter fullscreen mode Exit fullscreen mode

The code above follows the functional approach, the modern way to write react code. It took 30 lines of code.

In Class Component:

import { Component } from "react";
import { UNSPLASH_API, randomNum } from "../utils";

class RandomImageClass extends Component {
  constructor(props) {
    super(props);

    this.state = {
      count: 0,
      imgUrl: "",
    };
  }

  componentDidMount() {
    this.getData();
  }

  componentDidUpdate(prevProps, prevState) {
    if (this.state.count !== prevState.count) {
      this.getData();
    }
  }

  getData = async () => {
    const response = await fetch(UNSPLASH_API);
    const data = await response.json();
    this.setState({ imgUrl: data[randomNum(0, 10)]?.urls?.small });
  };

  render() {
    return (
      <div className="container">
        <div className="count">
          <h1>Total Renders →</h1>
          <h2>{this.state.count}</h2>
          <button
            className="btn"
            onClick={() => {
              this.setState({ count: this.state.count + 1 });
            }}
          >
            Render ✦
          </button>
        </div>
        <img src={this.state.imgUrl} />
      </div>
    );
  }
}

export default RandomImageClass;
Enter fullscreen mode Exit fullscreen mode

The code above took 55 lines of code, which is almost 2x compared to the functional approach. Even depending on complex logic, it will get more messy. So React took that message and upgraded upon it. But under the hood, it still processes the classical way. Functional components aim to make the developer's job easier than before. Functional components are nothing but a syntax sugar of the class component.

Top comments (0)