Home > Software design >  What does it mean 'componentMounted variable from inside React Hook useEffect will be lost afte
What does it mean 'componentMounted variable from inside React Hook useEffect will be lost afte

Time:10-16

Actually, I'm trying to get API data after loading buttons like men's clothing, women's clothing, etc. but only shows the 'Loading...' button does not show.

When I have tried initializing 'componentMounted' inside the useEffect, all errors are removed but again the buttons do not show.

import React, { useState, useEffect } from "react";

const Products = () => {
  const [data, setData] = useState([]);
  const [filter, setFilter] = useState(data);
  const [loading, setLoading] = useState(false);
  let componentMounted = true;

  useEffect(() => {
    const getProducts = async () => {
      setLoading(true);
      const response = await fetch("https://fakestoreapi.com/products");
      if(componentMounted) {
        setData(await response.clone().json());
        setFilter(await response.json());
        setLoading(false);
        console.log(filter);
      }
      return () => {
        componentMounted = false;
      }

    }

    getProducts();
  });

  const Loading = () => {
    return (<>Loading...</>);
  };

  const ShowProducts = () => {
    return (
      <>
        <div className="button">
          <button className="btn btn-outline-dark me-2">All</button>
          <button className="btn btn-outline-dark me-2">Men's Clothing</button>
          <button className="btn btn-outline-dark me-2">Women's Clothing</button>
          <button className="btn btn-outline-dark me-2">Jewelery</button>
          <button className="btn btn-outline-dark me-2">Electronics</button>
        </div>
      </>
    );
  };

  return (
    <>
      <div className="container my-5">
        <div className="row">
          <div className="col-12">
            <h1 className="display-6 fw-bolder text-center">Latest Products</h1>
            <hr />
          </div>
        </div>
        <div className="row justify-content-center">
          {loading ? <Loading /> : <ShowProducts />}
        </div>
      </div>
    </>
  );
};

export default Products;

The error message is:

"Assignments to the 'componentMounted' variable from inside React Hook useEffect will be lost after each render. To preserve the value over time, store it in a useRef Hook and keep the mutable value in the '.current' property. Otherwise, you can move this variable directly inside the useEffect"

CodePudding user response:

It's because you forgot to add the dependencies array which should be empty to load once and you can remove the componentMounted as it's not needed, your useEffect will be like this:

useEffect(() => {
  const getProducts = async () => {
    setLoading(true);
    const response = await fetch("https://fakestoreapi.com/products");
    setData(await response.clone().json());
    setFilter(await response.json());
    setLoading(false);
    console.log(filter);
  };

  getProducts();
}, []);

CodePudding user response:

It is not working because a dependency array wasnt provided. If a dependency array is not provided then your component will re-render in an infinite loop. Secondly, in order to use the unmount functionality, you have to use the return function of the useEffect.

You can find the fixed example here.

  • Related