Реагировать — Проблема с бесконечным циклом в эффекте использования

#reactjs #axios

Вопрос:

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

 const [products, setProducts] = useState([]);  useEffect(() =gt; {  const getProducts = async () =gt; {  return await axios  .get('/getAllProducts')  .then((response) =gt; {  setProducts(response.data);  console.log(products);  })  .catch((e) =gt; {  console.log(e);  });  };  getProducts();  }, [products]);  

Ответ №1:

Это связано с тем, что вы передали массив, содержащий ваше products состояние, а не пустой массив, который будет срабатывать useEffect при изменении состояния ( products в частности, для состояния). Попробуйте изменить свой код на пустой массив:

 useEffect(() =gt; { const getProducts = async () =gt; {  return await axios  .get('/getAllProducts')  .then((response) =gt; {  setProducts(response.data);  console.log(products);  })  .catch((e) =gt; {  console.log(e);  });  };  getProducts();  }, []);  

Как упоминалось ниже @skyboyer, полезно отметить, что состояние не обновляется синхронно. Поэтому console.log(products) при запуске не будет отображаться точное значение для вашего состояния useEffect .

Можно использовать несколько useEffect крючков. Если вы хотите просмотреть свое обновленное состояние в консоли или выполнить с ним какую-либо другую работу, вы можете добавить еще useEffect один хук и передать свое состояние в массив:

 useEffect(() =gt; {  console.log(products); }, [products]);  

Комментарии:

1. …а также удалить console.log(products) , чтобы удовлетворить ESLint, а также не выводить предыдущее значение, для products которого не имеет никакого смысла

2. я думаю, что он хочет видеть данные о результатах из состояния продукта после выполнения вызова из axios, поэтому он должен создать новый эффект использования отдельно от вызова, чтобы увидеть изменение данных.. useEffect(() =gt; { console.log(продукты);}, [продукты]);

Ответ №2:

Поскольку products он находится в массиве useEffect зависимостей, он будет запускаться каждый раз, когда в состояние вносятся изменения products . getProducts() запускается setProducts , что, в свою очередь, снова вызовет эффект использования. При использовании пустого массива в поле useEffect будет указано, что он запускается только при подключении компонента.

Подобный этому:

 useEffect(() =gt; { const getProducts = async () =gt; {  return await axios  .get('/getAllProducts')  .then((response) =gt; {  setProducts(response.data);  console.log(products);  })  .catch((e) =gt; {  console.log(e);  });  };  getProducts();  }, []);  

Комментарии:

1. Как ваш ответ влияет на тему дополнительно, чем ранее опубликованный ответ?