Error: Too many re-renders. React limits the number of renders to prevent an infinite loop
Появляется ошибка Too many re-renders если у меня вызывается функция в catch. Вообщем я имитирую поиск на сервере и если у меня возникает ошибка то я хочу выполнить поиск на клиенте. В cath я вызываю setData и вставляю туда filteredArray который выполняет поиск на клиенте. Тут выходит ошибка. Где я пишу код неверно? как исправить?
const fruitData = [
{ item: "Apple", id: 1 },
{ item: "Blueberry", id: 2 },
{ item: "Grape", id: 3 },
{ item: "Banana", id: 4 }
];
const App: React.FC = () => {
const [termInput, setTermInput] = useState<string>("")
const [data, setData] = useState<any>(fruitData)
const [loading, setLoading] = useState<boolean>(false)
}
const debouncedSearchTerm = useDebounce(termInput, 1000);
const visibleItems = (items:{item:string; id:number}[], termInput:string) => {
if (termInput.length === 0) {
setData(items)
}
return items.filter((item) => {
return item.item.toLowerCase().includes(termInput.toLowerCase())
})
}
const filteredArray = visibleItems(fruitData, termInput)
useEffect(() => {
if (!debouncedSearchTerm) return;
if (debouncedSearchTerm.length >= 0) {
const mockServerSearch = (debouncedSearchTerm: string, fruitData: { item: string; id: number }[]) => {
const isError = Math.round(Math.random())`введите сюда код`
const visibleItemsServer = (items: { item: string; id: number }[], debouncedSearchTerm: string) => {
if (debouncedSearchTerm.length === 0) {
return items;
}
return items.filter((item) => {
return item.item.toLowerCase().includes(debouncedSearchTerm.toLowerCase())
})
}
const filteredArrayServer = visibleItemsServer(fruitData, debouncedSearchTerm)
return new Promise((resolve, reject) => {
setLoading(true)
setTimeout(() => {
if (isError) resolve(filteredArrayServer)
else reject(new Error("Server search error"))
setLoading(false)
}, 2000)
})
}
mockServerSearch(debouncedSearchTerm, fruitData)
.then((filteredArrayServer) => {
setData(filteredArrayServer)
})
.catch(() => {
/*Тут я помещаю filteredArray в setData вместо моего начального состояния data*/
setData(filteredArray)
})
}
}, [debouncedSearchTerm])
const loader = loading ? <Loader /> : null;
const popup = !loading ? <PopupMenu
/*а тут я data передаю в другой компонент*/
fruits={data}
active={isActive}
setIsActive={setIsActive}
setSelected={selectItems}
selected={selected}
/> : null;
return (
<div
className="app"
>
<div className="page">
<SelectField
showMenu={showMenu}
selected={selected}
active={isActive}
deleteSelectedItem={deleteSelectedItem}
termInput={termInput}
setTermInput={setTermInput}
/>
{loader}
{popup}
</div>
</div>
);
/*другой компонент где я вставляю свой отфильтрованный массив*/
const PopupMenu: React.FC<DataProps> = props => {
const elements = props.fruits.map((fruit) => {
const { item, id } = fruit;
return (
<div key={id}
className={itemClassName}
onClick={() => {
props.setSelected(item)
}}
>
{item}
</div>
);
});
return (
<div className={className}>
{elements}
</div>
)
}
