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.
Notes: I removed the .slice
to see if that's causing the issue but it's not.
CodePudding user response:
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.