开发者问题收集

未捕获的 RangeError:调用自定义钩子时 React js 中的最大调用堆栈大小超出

2021-02-23
5072

我尝试从 Edit 组件发送 successerror 值,并将该值设置为 useAlert 挂钩。然后从 List 组件调用 useAlert 挂钩,并尝试根据 useAlert 挂钩返回的 successerror 值在 List 上方呈现消息。但是我在从 List 组件调用钩子时出现错误。

我的自定义钩子如下: useAlert.js :

import React from "react";

function useAlert(props){

    const [alert, setAlert] = useAlert("");

    useEffect(()=>{
        setAlert(props.alert);
    },[]);
    return alert;
}
export default useAlert;

从下面的组件,我调用自定义钩子: List.js :

import React,{useState, useEffect} from "react";
import axios from "axios";
import Moment from 'react-moment';
import {Link} from "react-router-dom";
import Pagination from "react-js-pagination";
import useAlert from "../hooks/useAlert.js";
import Error from "../alerts/Error.js";
import Success from "../alerts/Success.js";

function List(){

    const [alert, setAlert] = useState("");
    
    let alo = useAlert(alert);

    const [categories, setCategories] = useState([]);
    const [activePage, setActivePage] = useState(1);
    const [itemsCountPerPage, setItemsCountPerPage] = useState(0);
    const [totalItemsCount, setTotalItemsCount] = useState(0);

    useEffect(()=>{
        axios.get('http://127.0.0.1:8000/categories')
          .then(function (response) {
            console.log(response);
            setActivePage(response.data.current_page);
            setCategories(response.data.data);
            setItemsCountPerPage(response.data.per_page);
            setTotalItemsCount(response.data.total);
          })
          .catch(function (error) {
            console.log(error);
          });
    },[]);

    function handleClick(id){

        axios.delete('http://127.0.0.1:8000/delete/'+id)
          .then(function (response) {
            console.log(response);
            setActivePage(response.data.current_page);
            setCategories(response.data.data);
            setItemsCountPerPage(response.data.per_page);
            setTotalItemsCount(response.data.total);
          })
          .catch(function (error) {
            console.log(error);
          });
    }
    function handlePageChange(pageNumber) {
        console.log(`active page is ${pageNumber}`);
        
        axios.get('http://127.0.0.1:8000/categories?page='+pageNumber)
          .then(function (response) {
            console.log(response);
            setActivePage(response.data.current_page);
            setCategories(response.data.data);
            setItemsCountPerPage(response.data.per_page);
            setTotalItemsCount(response.data.total);
          })
          .catch(function (error) {
            console.log(error);
          });
      }

    return(
            <>
            
            {alo==="success" ? <Success msg="Category Updated successfully." />:null}

            <table className="table" style={{marginTop: "20px"}}>
              <thead>
                <tr>
                  <th scope="col">SL.</th>
                  <th scope="col">Name</th>
                  <th scope="col">Created_at</th>
                  <th scope="col">Updated_at</th>
                  <th scope="col">Edit</th>
                  <th scope="col">Delete</th>
                </tr>
              </thead>
              <tbody>
              {
                categories.map((category, index)=>{

                    return(
                            <tr key={index}>
                              <th scope="row">{index+1}</th>
                              <td>{category.name}</td>
                              <td><Moment format="D MMM YYYY">{category.created_at}</Moment></td>
                              <td><Moment format="D MMM YYYY">{category.updated_at}</Moment></td>
                              <td><Link to={`/edit/${category.id}`} className="btn btn-primary">Edit</Link></td>
                              <td><button onClick={()=>handleClick(category.id)} type="button" className="btn btn-danger">Delete</button></td>
                            </tr>
                        )
                })
              }
               
              </tbody>
            </table>

                <div className="d-flex justify-content-center">
                    <Pagination
                      activePage={activePage}
                      itemsCountPerPage={itemsCountPerPage}
                      totalItemsCount={totalItemsCount}
                      pageRangeDisplayed={5}
                      onChange={handlePageChange}
                      itemClass="page-item"
                      linkClass="page-link"
                    />
                </div>
            </>
        );
}

export default List;

我尝试了很多方法,但还是出现以下错误-->

Uncaught RangeError: Maximum call stack size exceeded
    at useAlert (app.js:2130)
    at useAlert (app.js:2131)
    at useAlert (app.js:2131)
    at useAlert (app.js:2131)
    at useAlert (app.js:2131)
    at useAlert (app.js:2131)
    at useAlert (app.js:2131)
    at useAlert (app.js:2131)
    at useAlert (app.js:2131)
    at useAlert (app.js:2131)

请任何专家检查代码并告诉我这里出了什么问题?我该如何解决?

2个回答

我在钩子中犯了一个错误,除了使用 useState 之外还调用了自身。如果对任何人都有帮助,我会回答我自己的问题。

正确的代码如下:

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

function useAlert(al){


    **const [alert, setAlert] = useState("");**   //made mistake here


    useEffect(()=>{
        setAlert(al);
    },[]);
    return alert;
}
export default useAlert;
smk pobon
2021-02-23

对我来说,问题在于循环依赖,但不是直接存在于两个主要自定义钩子之间,而是另一个 3er 钩子

useA > useB
useB > useC
useC > useA

为了解决这个问题,其中一个选项是将钩子分成更小的钩子以打破循环。

Juanma Menendez
2023-04-17