Junaid khan
Junaid khan

Reputation: 335

Uncaught Error: Rendered fewer hooks than expected. his may be caused by an accidental early return statement

Uncaught Error: Rendered fewer hooks than expected. his may be caused by an accidental early return statement. Here is the code. I am following a youtube tutorial by freecodecamp. In that tutorial it works OK but on my side, it is not working fine. I was expecting rendering of different product image that are present in the APi. Instead I am getting this error:

import React, { useEffect, useState } from "react";
import "./style.css";

export default function LoadMoreImages() {
  const [products, setProducts] = useState([]);
  const [count, setCount] = useState(0);
  const [loading, setLoading] = useState(false);
  const [disableButton, setDisableButton] = useState(false);

  async function fetchingProducts() {
    try {
      setLoading(true);
      const response = await fetch(
        `https://dummyjson.com/products?limit=20&skip=${
          count === 0 ? 0 : count * 20
        }`
      );
      const result = await response.json();

      if (result && result.products && result.products.length) {
        setProducts((prevData) => [...prevData, ...result.products]);
        setLoading(false);
      }
      console.log(result);
    } catch (e) {
      console.log(e);
      setLoading(false);
    }
  }

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

  if (loading) {
    return <div>Loading Data! Please wait for sometime</div>;
  }
  useEffect(() => {
    if (products && products.length === 100) setDisableButton(true);
  }, [products]);

  return (
    <div className="load-more-container">
      <div className="product-container">
        {products && products.length
          ? products.map((item) => (
              <div className="product" key={item.id}>
                <img src={item.thumbnail} alt={item.title} />
                <p>{item.title}</p>
              </div>
            ))
          : null}
      </div>

      <div className="button-container">
        <button disabled={disableButton} onClick={() => setCount(count + 1)}>
          Load More Products
        </button>
        {disableButton ? <p>You have reached 100 products</p> : null}
      </div>
    </div>
  );
}

Upvotes: 0

Views: 45

Answers (1)

Lin Du
Lin Du

Reputation: 102497

You can't put the react hooks code after condition statement such as if...else. Move the useEffect hook above if statement. See Rules of Hooks

Do not call Hooks after a conditional return statement.

Modified to this:

useEffect(() => {
  if (products && products.length === 100) setDisableButton(true);
}, [products]);

if (loading) {
    return <div>Loading Data! Please wait for sometime</div>;
}

You can see this example stackblitz

Upvotes: 1

Related Questions