【问题标题】:React Hooks Updating Array State Causes Infinite LoopReact Hooks 更新数组状态导致无限循环
【发布时间】:2021-05-11 02:32:33
【问题描述】:

我正在if 条件下更新我的nudgeList 状态。如果条件是true,我将一些对象插入到我的空状态数组中

  const [avgOrderCount, setAvgOrderCount] = useState('')
  const [productCategory, setProductCategory] = useState('')
  const [ecoPackage, setEcoPackage] = useState('')
  const [domesticDelivery, setDomesticDelivery] = useState('')
  const [foreignSalesTypeList, setforeignSalesTypeList] = useState([]
  const [nudgeList, setNudgeList] = useState([]) 

  if (Number(avgOrderCount) <= 9999) {
    if ((productCategory === ProductCategoryType.BEAUTY || productCategory === ProductCategoryType.SOME_BEAUTY) && ecoPackage === ecoPackageType.YES && domesticDelivery === domesticDeliveryType.YES && !foreignSalesTypeList.includes('open_market') && !foreignSalesTypeList.includes('export') && !foreignSalesTypeList.includes('none') && foreignSalesTypeList.length >= 1) {
      setNudgeList(list => [...list, eco, sample, orderSheet, wrongDelivery, oliveYoung, api, fifo, manager])
    }
  }

但是,在我测试我的代码后,我得到了错误

Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.

我怀疑问题在于我如何更新我的状态

setNudgeList(list => [...list, eco, sample, orderSheet, wrongDelivery, oliveYoung, api, fifo, manager])

但我很困惑为什么当我只有一个 if 条件时会触发无限循环。

如何解决此错误?

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    setNudgeList 将重新渲染您的组件。 但是你的if condition Number(avgOrderCount) &lt;= 9999 将永远是true 因此,每次渲染都会调用 setNudgeList。

    【讨论】:

    • 我明白了,它就像一个 while 循环总是卡在 true?
    【解决方案2】:

    如果您的条件为真,您将通过设置 NudgeList 来触发组件的重新渲染。在重新渲染中,如果您的条件仍然为真,设置 NudgeList 将触发下一次重新渲染,因此是无限循环。您应该使用效果来处理设置功能。例如:

    useEffect(()=>{
      if (Number(avgOrderCount) <= 9999) {
        if ((productCategory === ProductCategoryType.BEAUTY 
      || productCategory === ProductCategoryType.SOME_BEAUTY) 
      && ecoPackage === ecoPackageType.YES 
      && domesticDelivery === domesticDeliveryType.YES 
      && !foreignSalesTypeList.includes('open_market') 
      && !foreignSalesTypeList.includes('export') 
      && !foreignSalesTypeList.includes('none') 
      && foreignSalesTypeList.length >= 1) {
          setNudgeList(list => [...list, eco, sample, orderSheet, wrongDelivery, oliveYoung, api, fifo, manager])
        }
      }
    
    }, [avgOrderCount, productCategory...//all the dependence, sorry they are too many ])
    

    【讨论】:

      【解决方案3】:

      问题在于,在您的任何一种情况下,都没有阻止 setNudgeList 调用再次运行(或检查它是否已经运行)。因此,每次您的组件渲染时,它都会运行 setNudgeList 调用,这会触发重新渲染,再次调用 setNudgeList

      您可以通过将此逻辑包装在 useEffect 挂钩中并相应地设置依赖关系数组来解决此问题。只要您从依赖数组中省略 nudgeList 或在 useEffect 调用中包含对 nudgeList 值的检查,您就应该避免无限重新渲染。

      useEffect 挂钩仅在依赖数组中的任何值发生更改时调用给定的回调。这样您就可以控制哪些更改应该导致效果再次运行。

      例子:

        const [avgOrderCount, setAvgOrderCount] = useState('')
        const [productCategory, setProductCategory] = useState('')
        const [ecoPackage, setEcoPackage] = useState('')
        const [domesticDelivery, setDomesticDelivery] = useState('')
        const [foreignSalesTypeList, setforeignSalesTypeList] = useState([]
        const [nudgeList, setNudgeList] = useState([]) 
      
      
        React.useEffect(() => {
          if (Number(avgOrderCount) <= 9999) {
            if ((productCategory === ProductCategoryType.BEAUTY || productCategory === ProductCategoryType.SOME_BEAUTY) && ecoPackage === ecoPackageType.YES && domesticDelivery === domesticDeliveryType.YES && !foreignSalesTypeList.includes('open_market') && !foreignSalesTypeList.includes('export') && !foreignSalesTypeList.includes('none') && foreignSalesTypeList.length >= 1) {
              setNudgeList(list => [...list, eco, sample, orderSheet, wrongDelivery, oliveYoung, api, fifo, manager])
            }
          }
        }, [avgOrderCount, productCategory, ecoPackage, domesticDelivery, foreignSalesTypeList]);
      

      请注意,如果依赖数组(avgOrderCountproductCategoryecoPackagedomesticDeliveryforeignSalesTypeList)中的任何值发生更改,这仍会导致更新 nudgeList。因此,您可能还需要检查 nudgeList 的值或其他变量,以跟踪您是否已经更新了 nudgeList

      【讨论】:

        【解决方案4】:

        使用useEffect 可以解决问题

          useEffect(() => {
            if (Number(avgOrderCount) <= 9999) {
              if ((productCategory === ProductCategoryType.BEAUTY || productCategory === ProductCategoryType.SOME_BEAUTY) && ecoPackage === ecoPackageType.YES && domesticDelivery === domesticDeliveryType.YES && !foreignSalesTypeList.includes('open_market') && !foreignSalesTypeList.includes('export') && !foreignSalesTypeList.includes('none') && foreignSalesTypeList.length >= 1) {
                console.log('it works')
                setNudgeList(list => [...list, eco, sample, fedex, orderSheet, wrongDelivery, oliveYoung, api, fifo, manager])
              }
            }
          }, [avgOrderCount, productCategory, ecoPackage, domesticDelivery, foreignSalesTypeList])
        

        【讨论】:

          猜你喜欢
          • 2020-09-06
          • 1970-01-01
          • 1970-01-01
          • 2021-09-09
          • 1970-01-01
          • 2021-03-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多