当前位置: 首页 > 知识库问答 >
问题:

React JS Hooks-超过最大更新深度

巢星纬
2023-03-14

我有以下组件:-

import React, { useState, useEffect } from "react"
import Card from "./Card"

import joker from "../../assets/joker.png"
import goalie from "../../assets/goalie.png"
import defender from "../../assets/defender.png"
import midfielder from "../../assets/midfielder.png"
import attacker from "../../assets/attacker.png"

const CardsBoard = () => {

  const deckLimits = {
    joker: 4, goalkeepers: 12, defenders: 12, midfielders: 12, attackers: 12
  };

  const [ratingObj, setRatingObj] = useState({});
  const [visible1, setVisible1 ] = useState(false);
  const [visible2, setVisible2 ] = useState(false);
  const [deck, setDeck] = useState([]);
  const [deck1, setDeck1] = useState([]);
  const [deck2, setDeck2] = useState([]);
  const [currCardPl1, setCurrCardPl1] = useState({});
  const [currCardPl2, setCurrCardPl2] = useState({});

  useEffect(() => {
    generateDeck();
    distributeCards();
  }, [deck]);


  const startGame = () => {
    //reset decks
    setDeck([]);
    setDeck1([]);x
    setDeck2([]);

    //generate the card’s values
    generateDeck();
    if (deck.length > 0) {
      distributeCards();

      if (currCardPl1 != undefined){
        console.log(currCardPl1);
        //unMask ratings of Player 1
        setVisible1(true);
        setVisible2(false);
      }
    }
  };

  const distributeCards = () => {
      //randomize the deck
      deck.sort(() => Math.random() - 0.5);

      //distribute 26 cards at random when the game start
      const splitDeck1 = deck.slice(0, 26);
      const splitDeck2 = deck.slice(26, 52);
      //add this card to the deck
      splitDeck1.map((card) => {
        setDeck1(deck1 => [...deck1, card]);
      });
      //add this card to the deck
      splitDeck2.map((card) => {
        setDeck2(deck2 => [...deck2, card]);
      });
      
      //queue the first card to Player 1
      setCurrCardPl1(deck1[0]);      
      //queue the first card to Player 2
      setCurrCardPl2(deck2[0]);      
  };

  const generateDeck = () => {
    for (let i = 0; i < deckLimits.joker; i++) {
      generateCard('joker');
    };
    for (let i = 0; i < deckLimits.goalkeepers; i++) {
      generateCard('goalkeeper');
    };
    for (let i = 0; i < deckLimits.defenders; i++) {
      generateCard('defender');
    };
    for (let i = 0; i < deckLimits.midfielders; i++) {
      generateCard('midfielder');
    };
    for (let i = 0; i < deckLimits.attackers; i++) {
      generateCard('attacker');
    };
  }

  const generateCard = item => {
    const card = {
      player: 0,
      image: getImage(item),
      title: item.toUpperCase(),
      ratings: [
        { title: "Handling", rating: "99" },
        { title: "Reflexes", rating: "99" },
        { title: "Defending", rating: "99" },
        { title: "Strength", rating: "99" },
        { title: "Passing", rating: "99" },
        { title: "Flair", rating: "99" },
        { title: "Finishing", rating: "99" },
        { title: "Composure", rating: "99" },
      ],
    }

    //add this card to the deck
    setDeck(deck => [...deck, card]);
  }

  const getImage = item => {
    switch (item) {
      case "joker":
          return joker;
      case "goalkeeper":
          return goalie;
      case "defender":
          return defender;
      case "midfielder":
          return midfielder;
      case "attacker":
          return attacker;
      default:
        break;
    }
  };

  return (
    <div className="container-fluid justify-content-center">
      <div className="row">
        <div className="col-md-6">
          <div>
            <h4>Player 1</h4>
          </div>
          <Card
            cardInfo={currCardPl1}
            showRatings={visible1}
            onClick={ratingObj => setRatingObj(ratingObj)}
          />
        </div>
        <div className="col-md-6">
          <h4>Player 2</h4>
          <Card
            cardInfo={currCardPl2}
            showRatings={visible2}
            onClick={ratingObj => setRatingObj(ratingObj)}
          />
        </div>
      </div>
      <div className="row top-buffer">
        <div className="col-md-12 text-center">
          <button
            id="startGameBtn"
            name="StartGameButton"
            className="btn btn-secondary"
            onClick={() => startGame()}
          >
            START GAME
          </button>
        </div>
      </div>
    </div>
  )
}

export default CardsBoard

我得到了错误:-

Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.

我怀疑它必须对多次调用setState的Submit按钮(onClick)做一些事情,但是我似乎无法解决问题。

因此,我有以下问题:-

  1. 如何修复点击()?
  2. 我想点击开始游戏按钮,然后触发生成Deck();分发卡片(); 这样我就可以填满套牌,套牌1和套牌2。有没有办法做到这一点?目前,我已经创建了一个useEffect(),这取决于正在填充的甲板,这是用钩子做的正确方法吗?

谢谢你的帮助和时间!

共有3个答案

古棋
2023-03-14
deck.sort(() => Math.random() - 0.5);

你这里有一个问题。将它保存在一个变量中。否则你会在调用它的时候一直更新状态。

穆承运
2023-03-14
匿名用户

在< code>distributeCards中使用< code>setDeck(),在< code>useEffect挂钩中,再次调用< code > distribute cards

  const distributeCards = () => {
  // bla bla
       setDeck(deck => [...deck, card]);
  }   

这导致一直调用钩子。

useEffect(() => {
    generateDeck();
    distributeCards();
  }, [deck]);

南门宇
2023-03-14

您在useEffects挂钩中有一个依赖项。这意味着GenerateDeck将在每次更新套牌时运行。但是,GenerateDeck调用GenerateCard,后者调用setDeck。这会导致套牌发生变化,这意味着您陷入了一种无限循环。您应该将GenerateDeck绑定到onClick处理程序或其他不会被套牌更改触发的事件。

此外,请注意:

deck.sort(() => Math.random() - 0.5)

调用sort会直接改变您的状态,这是您应该在React中避免的。试试setDeck(d=

 类似资料:
  • 超过了最大更新深度。当组件重复调用组件WillUpdate或组件DidUpdate中的setState时,可能会发生这种情况。React限制嵌套更新的数量以防止无限循环。 这是bossinfo.js 这是user.redux.js 你为什么一直报告这个问题?这是指向错误的方向吗?寻求帮助

  • 我遇到一个错误: 超过了最大更新深度。当组件重复调用componentWillUpdate或componentDidUpdate内部的setState时,会发生这种情况。React限制嵌套更新的数量,以防止无限循环。 我的代码是: 我有另一个使用路由器切换页面的组件,以及一个包含登录页面的邮件组件。

  • 当我运行我的代码时,我收到了这个错误。 超过了最大更新深度。当组件重复调用组件WillUpdate或组件DidUpdate中的setState时,可能会发生这种情况。React限制嵌套更新的数量以防止无限循环。 这是代码。它在引用。 我按照React网站上的文章所说的方式设置了我的东西,它“来了”于这个简洁的控制台类型,这就是我产生上述代码的地方。我对React、JSX和Javascript(以及

  • 当我试图设置表单错误对象时,我遇到了这个问题。基本上,我想在每个输入字段下方显示错误。作为回应,我得到了一个对象数组,我如何设置我的错误对象? 错误-超过了最大更新深度。当组件在useEffect内部调用setState,但useEffect没有依赖关系数组,或者每次呈现时依赖关系之一发生变化时,就会发生这种情况。

  • 我正在使用FullCalendar进行反应,我正在与状态作斗争……它返回以下消息: 错误:超过最大更新深度。当组件在componentWillUpdate或componentDidUpdate内重复调用setState时,可能会发生这种情况。React限制嵌套更新的数量,以防止无限循环。 我删除了代码中所有不必要的部分。 如果您想让我提供更多信息,请告诉我。欢迎任何反馈/想法!谢谢

  • 这是我的一段代码: 但这给了我错误,说超过了最大更新深度。当组件重复调用组件内部的 setState 时,可能会发生这种情况“组件将更新”或“组件更新”。React 限制嵌套更新的数量,以防止无限循环。 这是一个快照: 我该如何解决这个问题?