Home > Enterprise >  Uncaught Error: Rendered more hooks than during the previous render when trying to have a nested loo
Uncaught Error: Rendered more hooks than during the previous render when trying to have a nested loo

Time:10-28

I know same question probably asked multiple times. But I couldn't find the answer I'm looking for.

This is the code for Task:

import Navbar from './Navbar';
import "./Idea.css";
import GetData from '../restApiMethods/GetData';
import React from "react";

function Task() {
    const ids = GetData("ideas/id");
    return (
        <div>
            <Navbar />
            <div className="idea-design">   
                <div className="container">
                    {
                        ids.map((id,index) => {
                            return (
                            <div key={index}>
                                {
                                GetData(`ideas/${id}`).map((task,index) => {
                                    return(
                                        <div key={index} className="row border border-secondary">
                                            <div className="col">
                                                <div> 
                                                    <p>{task.taskDescription}</p>
                                                </div>
                                            </div>
                                        </div>
                                    )
                                })
                                }
                            </div>
                            )
                        })
                    }
                </div>
                </div>
            </div>
      
      )
}

export default Task

Getdata dunction:

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

function GetData(data) {

    const [datas, setDatas] = useState([]);

    useEffect(() =>{ 
    const fetchData = () => {
    axios.get(`http://localhost:8080/api/${data}`).then(res =>{
    console.log(res);
    setDatas(res.data);
        });
    };
        fetchData();
    }, []);
      
    return datas;
}

export default GetData

If someone can give me some idea why I'm getting this error: Rendered more hooks than during the previous render, would be really helpful.

CodePudding user response:

GetData actually is a custom hook because it's a function that calls hooks. Therefore subject to the rules of hooks.

It should be called useGetData -- I'll refer to it as that for this answer. You can't call it in a loop, as when the ids array changes length, the number of calls to useGetData will change in the parent component Task. This isn't allowed in React because hooks are supposed to be in a predictable order and never change -- its a declarative model.

To fix this, break out a new component called Task (rename your current one to Tasks or whatever makes sense for you) and call it once in there. This doesn't break the rules of hooks as it is only within a component that the number of calls can't change between renders.

Tasks

import Navbar from "./Navbar";
import "./Idea.css";
import useGetData from "../restApiMethods/useGetData";
import React from "react";

import Task from "./Task";

function Tasks() {
  const ids = GetData("ideas/id");
  return (
    <div>
      <Navbar />
      <div className="idea-design">
        <div className="container">
          {ids.map((id, index) => {
            return <Task id={id} key={id} />;
          })}
        </div>
      </div>
    </div>
  );
}

export default Tasks;


Task

export default function Task({ id }) {
  const data = useGetData(`ideas/${id}`);
  return (
    <div>
      {data.map((task, index) => {
        return (
          <div key={index} className="row border border-secondary">
            <div className="col">
              <div>
                <p>{task.taskDescription}</p>
              </div>
            </div>
          </div>
        );
      })}
    </div>
  );
}

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

function useGetData(data) {
  const [datas, setDatas] = useState([]);

  useEffect(() => {
    const fetchData = () => {
      axios.get(`http://localhost:8080/api/${data}`).then((res) => {
        console.log(res);
        setDatas(res.data);
      });
    };
    fetchData();
  }, []);

  return data;
}

export default useGetData;

  • Related