Моя проблема в том, что я пытаюсь показать данные (список элементов) на первом рендере, используя useEffect с хуками useState, и после того, как он рендерится, я хочу отфильтровать эти сопоставленные элементы.

В тот момент, когда я попадаю на страницу элементов, я получаю ноль элементов, отображаемых на странице. И они отображаются только после того, как я отфильтрую их (либо с помощью фильтра поиска, либо выбрав нужный цвет из выпадающего списка).

Ниже я показываю свой код:

... var [searchTerm, setSearchTerm] = useState{amp}lt;any{amp}gt;(""); var [searchResults, setSearchResults] = useState{amp}lt;any{amp}gt;([]); const handleInput = (e: any) ={amp}gt; { console.log(e.target.value); setSearchTerm(e.target.value); }; var [pickedColor, setPickedColor] = useState{amp}lt;any{amp}gt;(""); var [colorPickResults, setColorPickResults] = useState{amp}lt;any{amp}gt;([]); const handleColorChange = (e: any) ={amp}gt; { console.log(e.target.value); setPickedColor(e.target.value); }; var [items, setItems] = useState{amp}lt;any{amp}gt;([]); useEffect(() ={amp}gt; { var message: string = ""; var fetchItems = () ={amp}gt; { axios .get("/api/products") .then((res: any) ={amp}gt; { console.log("res :", res); setItems(res.data.data[0].products); console.log("res.data.data[0].products :", res.data.data[0].products); if (res.status === 200) { message = "Products successfuly fetched."; console.log(message); } else { message = "Something went wrong. Please try again later."; console.log(message); } }) .catch((err: any) ={amp}gt; console.log(err)); }; fetchItems(); const resultsFromSearch = items.filter((item: any) ={amp}gt; item.title.toLowerCase().includes(searchTerm) ); setSearchResults(resultsFromSearch); const resultsFromPickedColor = resultsFromSearch.filter((item: any) ={amp}gt; item.color.toLowerCase().includes(pickedColor) ); setColorPickResults(resultsFromPickedColor); }, [searchTerm, pickedColor]); var filteredItems = colorPickResults; var itemList = filteredItems.map((item: any) ={amp}gt; { return ( {amp}lt;div key={item.id} style={{ width: "370px", padding: "1rem" }}{amp}gt; ... 

Я получаю успешное сообщение в консоли, и элемент успешно извлекается, как я упоминал выше.

Что я пробовал: 1. Добавление «items» в массив: [searchTerm, selectedColor, items], но затем useEffect создает бесконечный цикл при извлечении элементов и (возможно) повторное рендеринг компонента при каждом извлечении.

Что я могу изменить, чтобы получить желаемую функциональность, упомянутую в начале моего сообщения? Должен ли я добавить некоторые другие хуки, такие как useContext, useMemo? А может я могу как-то отделить выборку от фильтрации?

вызов асинхронной функции и попытка доступа к данным, которые она вернет куда-то позже, никогда не будут работать так, как вы ожидаете

 fetchItems(); const resultsFromSearch = items.filter((item: any) ={amp}gt; item.title.toLowerCase().includes(searchTerm) ); в fetchItems(); const resultsFromSearch = items.filter((item: any) ={amp}gt; item.title.toLowerCase().includes(searchTerm) ); 

Вы должны либо добавить этот код в .then внутри fetchItems либо, возможно, использовать отдельный useEffect :

 useEffect(() ={amp}gt; { const resultsFromSearch = items.filter((item: any) ={amp}gt; item.title.toLowerCase().includes(searchTerm) ); setSearchResults(resultsFromSearch); }, [items]) в useEffect(() ={amp}gt; { const resultsFromSearch = items.filter((item: any) ={amp}gt; item.title.toLowerCase().includes(searchTerm) ); setSearchResults(resultsFromSearch); }, [items]) 

Для меня второй вариант более декларативный и более гибкий, но это зависит от вас