Функция для получения данных продолжает работать в цикле

У меня есть функция, которая получает некоторые данные из моего бэкэнда, а затем я хочу просто присвоить их состоянию и отобразить в своем браузере. Все работает правильно, но я не знаю, почему, когда я запускаю запрос, функция продолжает вызывать API без остановки. Что является причиной этого? Кажется, что функция застряла в каком-то цикле while-true.

function App() {
  const [orders, setOrders] = useState();

  const getOrders = async () => {
    const response = await axios.get("/api/orders/");
    setOrders(response);
    console.log(response);
  };
  getOrders();
  return <div className="App">{JSON.stringify(orders)}</div>;
}

export default App;

multiple calls to the backend

Я бы предложил добавить debugger; выше const response = await axios.get("/api/orders/"); и проверить стек вызовов в среде отладки.

AlexMA 22.05.2019 15:33

Вы начинаете визуализировать компонент, а также создаете асинхронный запрос, который разрешится через некоторое время. Рендеринг завершается, и через некоторое время завершается ваш асинхронный запрос. Это вызовет повторную визуализацию, которая, в свою очередь, создаст новый асинхронный запрос и так далее до бесконечности.

Etheryte 22.05.2019 15:34
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Сравнение структур данных: Массивы и объекты в Javascript
Сравнение структур данных: Массивы и объекты в Javascript
Итак, вы изучили основы JavaScript и хотите перейти к изучению структур данных. Мотивация для изучения/понимания Структур данных может быть разной,...
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Прошлая статья была первой из цикла статей о создании системы электронной коммерции с использованием Keystone.js, и она была посвящена главным образом...
Приложение для отслеживания бюджета на React js для начинающих
Приложение для отслеживания бюджета на React js для начинающих
Обучение на практике - это проверенная тема для достижения успеха в любой области. Если вы знаете контекст фразы "Практика делает человека...
Стоит ли использовать React в 2022 году?
Стоит ли использовать React в 2022 году?
В 2022 году мы все слышим о трендах фронтенда (React, Vue), но мы не знаем, почему мы должны использовать эти фреймворки, когда их использовать, а...
1
2
45
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы хотите использовать хук Effect, который предлагает React:

https://reactjs.org/docs/hooks-effect.html

function App() {
    const [orders, setOrders] = useState();

    const getOrders = async () => {
        const response = await axios.get("/api/orders/");
        setOrders(response);
        console.log(response);
    };

    useEffect(() => {
       getOrders();
    }, []); //Empty array = no dependencies = acts like componentDidMount / will only run once

    return <div className="App">{JSON.stringify(orders)}</div>;
}

export default App;

Я думаю, что вы используете здесь хуки реакции, поэтому ваша функция getOrders все время получает рендеринг.

Используйте useEffect от реакции, чтобы избежать этого.

    function App() {
      const [orders, setOrders] = useState();

      useEffect(() => {
const getOrders = async () => {
        const response = await axios.get("/api/orders/");
        setOrders(response);
        console.log(response);
      };
      getOrders();
}, [])
      return <div className="App">{JSON.stringify(orders)}</div>;
    }

    export default App;
Ответ принят как подходящий

What is the reason for this?

Это происходит потому, что вы вызываете функцию при каждом рендеринге внутри функционального компонента.

  const getOrders = async () => {
    const response = await axios.get("/api/orders/");
    setOrders(response); // this will re render the component
    console.log(response);
  };
  getOrders(); // this will be called every render and cause the infinity loop

Когда вы визуализируете компонент, вы вызываете getOrders, а эта функция вызывает setOrders, которая повторно визуализирует компонент, вызывая бесконечный цикл.


Первый рендер => вызов getOrders => вызов setOrders => Ререндеринг =>

Второй рендер => вызов getOrders => вызов setOrders => Ререндер =>
...


Вам нужно использовать хук useEffect или вызвать функцию для какого-либо события (возможно, нажатие кнопки)

например используя useEffect

function App() {
    const [orders, setOrders] = useState(null);

    useEffect(() => {
        const getOrders = async () => {
            const response = await axios.get("/api/orders/");
            setOrders(response);
            console.log(response);
        };
       getOrders();
    }, []); 

    return <div className="App">{JSON.stringify(orders)}</div>;
}

Другие вопросы по теме