Реагируйте на бесконечный цикл useEffect при извлечении из api

#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.