FabricioG
FabricioG

Reputation: 3310

react useState enters infinite loop even thou variable is the same

I have the following code:

  const [ ddFilterData, setddFilterData ] = useState('');



useEffect(() => {
      getDropdownData();
  }, [ddFilterData]);

const getDropdownData = async () => {
  if(optionDetails) {
    let filteredData = Promise.all(
      optionDetails.map(async (item, i) => {
          const fltData = await filterData(item, props.items);
          return fltData
        })
      )
      filteredData.then(returnedData => {
        setddFilterData(returnedData);
      })

  }

}

What I need is for useEffect to execute eah time ddFilerData changes with NEW or DIFFERENT data. From my understanding it should only update or run when teh ddFilterData is different no?

Currently it runs on each change. The code above enters into an infinite loop even thou filteredData isn't different. Any ideas what I'm doing wrong?

Upvotes: 0

Views: 51

Answers (2)

dalmo
dalmo

Reputation: 443

Your returnedData is an array. So when you do setddFilterData(returnedData) you're setting a new value for ddFilterData. Because React uses Object.is for comparison, even if the array elements are the same as previously, it is still a different object and will trigger useEffect again, causing the infinite loop.

Upvotes: 3

Rahul
Rahul

Reputation: 5834

your getDropdownData method is updating ddFilterData which causes re-render. And on re-render you getDropdownData is called which updated ddFilterData due to this cyclic behavior your are getting infinte loop.

Modify your code like this:

  const [ ddFilterData, setddFilterData ] = useState('');

useEffect(() => {
  getDropdownData();
}, []);

useEffect(() => {
 // put your code here if you want to do something on change of ddFilterData
}, [getDropdownData]);


const getDropdownData = async () => {
  if(optionDetails) {
    let filteredData = Promise.all(
    optionDetails.map(async (item, i) => {
      const fltData = await filterData(item, props.items);
      return fltData
    })
  )
  filteredData.then(returnedData => {
    setddFilterData(returnedData);
  })

 }

}

Upvotes: 0

Related Questions