Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Replacing an entire array in state React Hooks – error Too many re-renders. React limits the number of renders to prevent an infinite loop

I have an array of items stored in state and rendered when the component loads. I’m attempting to replace this array with a filtered array but I’m getting the error:

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

Here’s the code:


let filteredItemsArray: IListItems[] = [];

 if (searchInputTitle.length > 0) { //This is if it's filtered or not:
        filtered = !searchInputTitle ? requests : requests.filter((title) => title.Title.toLowerCase().includes(searchInputTitle.toLowerCase()));
        setFilteredItemsArrayState(filtered);
    } else {
        let sortedByID: IListItems[] = requests.sort((a, b) => a.Id > b.Id ? 1 : -1);
        filteredItemsArray = sortedByID;
        setFilteredItemsArrayState(filteredItemsArrayState => [...filteredItemsArrayState, ...filteredItemsArray]);
    }

///Render:

  <DetailsList className={styles.DetailsList}
       items={filteredItemsArrayState.slice((ListPage - 1) * 50, ((ListPage * 50)))}
      />

As you can see I’m attempting to use spread operators to replace the old array with the new, but it’s not working.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Notes: I removed the .slice to see if that’s causing the issue but it’s not.

>Solution :

You need to wrap this code into a useEffect function:

if (searchInputTitle.length > 0) { //This is if it's filtered or not:
        filtered = !searchInputTitle ? requests : requests.filter((title) => title.Title.toLowerCase().includes(searchInputTitle.toLowerCase()));
        setFilteredItemsArrayState(filtered);
    } else {
        let sortedByID: IListItems[] = requests.sort((a, b) => a.Id > b.Id ? 1 : -1);
        filteredItemsArray = sortedByID;
        setFilteredItemsArrayState(filteredItemsArrayState => [...filteredItemsArrayState, ...filteredItemsArray]);
    }

With the code you have, every time the page render, it will execute the if-else statement and update the state so this mean, the page will re-render constantly.

The solution:

useEffect(() => {
if (searchInputTitle.length > 0) { //This is if it's filtered or not:
        filtered = !searchInputTitle ? requests : requests.filter((title) => title.Title.toLowerCase().includes(searchInputTitle.toLowerCase()));
        setFilteredItemsArrayState(filtered);
    } else {
        let sortedByID: IListItems[] = requests.sort((a, b) => a.Id > b.Id ? 1 : -1);
        filteredItemsArray = sortedByID;
        setFilteredItemsArrayState(filteredItemsArrayState => [...filteredItemsArrayState, ...filteredItemsArray]);
    }
}, [searchInputTitle])

With the solution, the function only get executed when searchInputTitle change and not every time.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading