#reactjs #state #use-effect
#реагирует на #государство #эффект использования
Вопрос:
Я пытаюсь сохранить данные из моего запроса на извлечение в состояние, но это приводит к бесконечному циклу, даже если зависимости нет. Когда я удаляю код внутри div, где я отфильтровываю и отображаю массив, кажется, что он не бесконечно зацикливается, но я понятия не имею, почему фильтрация/сопоставление приведет к такому циклу
function App() { const [searchTerm, setSearchTerm] = useState(""); const [students, setStudents] = useState([]); const [isActive, setIsActive] = useState(false); const average = (array) =gt; { return array.reduce((a, b) =gt; a parseFloat(b), 0) / array.length; }; useEffect(() =gt; { const api = async () =gt; { await fetch("https://api.hatchways.io/assessment/students") .then((res) =gt; res.json()) .then((data) =gt; setStudents(data.students)); }; api(); }, []); return ( lt;div className='bg-gray-300 h-screen flex items-center justify-center'gt; {students .filter((student) =gt; { if (searchTerm === "") { return student; } else if ( student.firstName .toLowerCase() .includes(searchTerm.toLowerCase()) || student.lastName.toLowerCase().includes(searchTerm.toLowerCase()) ) { return student; } }) .map((student, i) =gt; ( lt;div key={i} className='flex items-center space-x-8 px-8 py-3 border-b'gt; lt;div className='flex items-start w-full space-x-7'gt; lt;div className='border overflow-hidden rounded-full'gt; lt;img className='w-24 h-24 bg-contain' src={student?.pic} alt='student school portrait' /gt; lt;/divgt; lt;div className='flex flex-col justify-between space-y-4 w-full'gt; lt;div className='flex items-center justify-between'gt; lt;h1 className='font-bold text-5xl'gt; {student?.firstName} {student?.lastName} lt;/h1gt; lt;button onClick={setIsActive(!isActive)}gt; {isActive ? ( lt;AiOutlinePlus className='h-7 w-7' /gt; ) : ( lt;AiOutlineMinus className='h-7 w-7' /gt; )} lt;/buttongt; lt;/divgt; lt;div className='pl-3'gt; lt;pgt;Email: {student?.email}lt;/pgt; lt;pgt;Company: {student?.company}lt;/pgt; lt;pgt;Skill: {student?.skill}lt;/pgt; lt;pgt;Average: {average(student?.grades).toFixed(2)}%lt;/pgt; lt;/divgt; lt;/divgt; lt;/divgt; lt;/divgt; ))} lt;/divgt; ); }
Ответ №1:
Если вы используете async/await
, вам не нужно цепляться .then()
. Попробуйте обновить свой эффект использования, как :
useEffect(() =gt; { api(); }, []); const api = async () =gt; { let res = await fetch("https://api.hatchways.io/assessment/students"); let data = await res.json(); setStudents(data.students) };
Кроме того, используйте функцию стрелки в обработчике нажатия кнопки как:
lt;button onClick={()=gt;setIsActive(!isActive)}gt;
Комментарии:
1. Просто попытался использовать это, но все равно не повезло, по какой-то причине у меня возникла проблема с использованием setStudents внутри useeffect
2. Импорт правильный, у меня также есть это, а также состояние использования, и у меня есть состояние заполнителя моих студентов в виде пустого массива
3. @Стивенсмит, пожалуйста, попробуйте с обновленным ответом, первым кодом.
4. Я только что попробовал, но это все равно повторяется бесконечно. ему не нравится, когда я по какой-то причине устанавливаю студентов внутри эффекта использования.
5. @StevenSmith Переместите функцию за пределы эффекта использования
Ответ №2:
в основном я пытаюсь вызвать функцию внутри useEffect, в то время как код для этой функции находится вне useEffect. это работает для меня, попробуй это.
useEffect(() =gt; { api(); }, []); const api = async () =gt; { await fetch("https://api.hatchways.io/assessment/students") .then((res) =gt; res.json()) .then((data) =gt; setStudents(data.students)); };
Комментарии:
1. Я только что попробовал это, но у меня все еще есть проблема с тем, что я делаю setStudents(данные) после . затем цепи
Ответ №3:
Попробуйте с async-await
синтаксисом
useEffect(() =gt; { const fetchData = async () =gt; { const response = await fetch( "https://api.hatchways.io/assessment/students" ); const result = await response.json(); console.log("res", result); }; fetchData(); }, []);
В случае, если вы хотите обрабатывать ошибки, вам необходимо добавить блок try catch.
Комментарии:
1. В моем коде уже реализована асинхронность/ожидание
Ответ №4:
Проблема заключалась в том, что не была установлена функция стрелки при нажатии кнопки: lt;button onClick={() =gt; setIsActive(!isActive)}gt;
Ответ №5:
lt;button onClick={setIsActive(!isActive)}gt;
Это может быть виновником. Вы меняете состояние в каждом рандере. Вместо этого вы должны передать () =gt; setIsActive(!isActive)
как обработчик onClick.