Как остановить блок Гутенберга от запуска нескольких запросов GET?


Я создавал блок Гутенберга, который отправляет запрос GET в API REST Woocommerce.

Он состоит из текста input, который получает идентификатор продукта и отправляет его в API REST Woocommerce. В нем также есть button, который запускает функцию для извлечения продукта с помощью API.

Проблема с запросами GET

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

Я импортирую WooCommerceRestApi из "@woocommerce/woocommerce-rest-api" и использую Node.js .

Код

Это первая часть функции редактирования:

const edit = ({ attributes, setAttributes }) => {

    const blockProps = useBlockProps();

    // Wrapped the WooCommerce.get() function in a function named `fetchingId` to call it with a button
    const fetchingId = async (id) => {
      // The WooCoommerce.get() function
      const response = await WooCommerce.get(`products/${id}`)
        .then((response) => {
          console.log(response.data);
          setAttributes({ price: response.data.price });
          setAttributes({ name: response.data.name });
        })
        .catch((error) => {
          console.log(error.response.data);
          setAttributes({ price: '' });
          setAttributes({ name: '' });
        });
    }

    ...

  }

Это еще одна часть функции: ввод, который обновляет Product ID, используемый для запроса GET, и кнопка, связанная с функцией fetchingId().

return <div {...blockProps}>
    <div class="wrapper-input" >
        <TextControl
          label={__('ID du Produit', 'ingredient-unique')}
          value={attributes.id}
          onChange={(val) => setAttributes({ id: val })}
          className='control-id'
        />
    </div>
    <button onclick={fetchingId(attributes.id)}>Chercher le produit</button>

    ...
</div>;
Author: JAGENI Nat, 2021-02-10

1 answers

Вы не должны делать HTTP-запросы и т. Д. Непосредственно внутри компонентов React, вам нужно использовать useEffect.

Компонент react должен запускаться как можно быстрее, даже если работа, которую необходимо выполнить, еще не завершена. Используя useEffect, вы указываете React запустить отдельную функцию после завершения рендеринга, что дает вам возможность делать запросы и чтобы ваш компонент имел "эффекты". React также позволяет вам передать список зависимостей, которые он будет отслеживать, и если они изменят эффект повторяется.

Однако у вас есть побочный эффект, который работает непосредственно в компоненте. В результате всякий раз, когда компонент повторно визуализируется, ваш код выполняет HTTP-выборку, что, помимо этой проблемы, также значительно замедлит работу редактора. Повторный рендеринг может произойти в любое время по замыслу. Изменение размера окна, случайное событие dom, изменения состояния родительских компонентов и т. Д.

Если это поможет, обычный способ показать это с помощью чего-то вроде этого:

const { isLoading, setLoading } = useState( false );

Таким образом, вы может вызвать setLoading( false ) в конце вашей функции useEffect, а затем отобразить сообщение о загрузке в компоненте

Это еще одна часть функции: ввод, обновляющий идентификатор продукта, используемый для запроса GET, и кнопка, связанная с функцией fetchingId().

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

 2
Author: Tom J Nowell, 2021-02-10 11:30:52