0

I am updating my nudgeList state within an if condition. If the condition is true, I insert a number of objects into my empty state array

  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])
    }
  }

However, after I test my code I get the error

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

I suspect the problem lies with how I am updating my state

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

But I am confused why this is triggering an infinite loop when I just have one if condition.

How do I resolve this error?

4 Answers 4

1

setNudgeList will re-render your component. But your if condition Number(avgOrderCount) <= 9999 will always true So, setNudgeList will be called every render.

Sign up to request clarification or add additional context in comments.

1 Comment

I see so it works like a while loop always stuck on true?
1

if your condition is true, you will trigger a Re-render of the component by setting the NudgeList. In the Re-render, if your condition is still true, setting NudgeList will trigger the next Re-render, hence the infinite loop. you should use effect to handle the setting function. For example:

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 ])

Comments

1

The issue is that there's nothing in either of your conditions that prevents the setNudgeList call from being run again (or a check that it has already run). So each time your component renders, it runs the setNudgeList call, which triggers a re-render, which again invokes setNudgeList.

You can fix this by wrapping this logic within a useEffect hook and setting the dependency array accordingly. As long as you either omit nudgeList from the dependency array or include a check on the value of nudgeList within the useEffect call you should avoid infinite re-renders.

The useEffect hook only calls the given callback when the value of anything in the dependency array changes. This way you can control which changes should cause the effect to run again.

Example:

  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]);

Note this will still cause nudgeList to be updated if any of the values in the dependency array (avgOrderCount, productCategory, ecoPackage, domesticDelivery, or foreignSalesTypeList) changes. So you may also want to add a check on the value of nudgeList or another variable to keep track of whether you've already updated nudgeList or not.

Comments

0

Using useEffect fixes the problem

  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])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.