admin管理员组文章数量:1303536
I've been building a Gutenberg Block that sends a GET
request to the Woocommerce REST API.
It is composed of a text input
that receives an ID of a product and fetches it to the Woocommerce REST API. It also has a button
that fires a function to fetch the product with the API.
The issue with the GET Requests
The fetching works well, but it keeps sending multiple GET
requests, even when I do not click the button to fire the function. Simply clicking the input sends multiple requests when I only need one everytime I change the ID and click the button.
I'm importing WooCommerceRestApi
from "@woocommerce/woocommerce-rest-api"
and use Node.js.
The code
This is the first part of the edit function:
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: '' });
});
}
...
}
This is another part of the function: an input that updates the Product ID
that is used for the GET
request and a button linked to the fetchingId()
function.
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>;
I've been building a Gutenberg Block that sends a GET
request to the Woocommerce REST API.
It is composed of a text input
that receives an ID of a product and fetches it to the Woocommerce REST API. It also has a button
that fires a function to fetch the product with the API.
The issue with the GET Requests
The fetching works well, but it keeps sending multiple GET
requests, even when I do not click the button to fire the function. Simply clicking the input sends multiple requests when I only need one everytime I change the ID and click the button.
I'm importing WooCommerceRestApi
from "@woocommerce/woocommerce-rest-api"
and use Node.js.
The code
This is the first part of the edit function:
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: '' });
});
}
...
}
This is another part of the function: an input that updates the Product ID
that is used for the GET
request and a button linked to the fetchingId()
function.
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>;
Share
Improve this question
asked Feb 10, 2021 at 10:13
JAGENI NatJAGENI Nat
254 bronze badges
1
|
1 Answer
Reset to default 2You're not supposed to make HTTP requests etc directly inside React components, you need to use useEffect
.
A react component needs to run as quickly as possible, even if work that needs doing isn't finished yet. By using useEffect
you tell React to run a separate function after rendering is complete, giving you the opportunity to make requests and for your component to have "effects". React also lets you pass a list of dependencies that it will watch, and if they change the effect re-runs.
What you have however, is a side effect that runs directly in the component. As a result, whenever the component is re-rendered, your code makes a HTTP fetch, which aside from this problem is also going to significantly slow down the editor. A re-render could happen at any time by design. A window resize, stray dom event, state changes in parent components, etc
If it helps, a common way to show this is with something like this:
const { isLoading, setLoading } = useState( false );
This way you can call setLoading( false )
at the end of your useEffect
function, and then display a loading message in the component
This is another part of the function: an input that updates the Product ID that is used for the GET request and a button linked to the fetchingId() function.
You cannot rely on those values being present here. You can trigger a function via an event, and that function can have side effects such as HTTP requests, but you can't do those things directly in the component. Rendering the component should render the component, and only render the component, everything else goes in lifecycle hooks/functions
本文标签: woocommerce offtopicHow to stop a Gutenberg Block from firing multiple GET Requests
版权声明:本文标题:woocommerce offtopic - How to stop a Gutenberg Block from firing multiple GET Requests? 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741760757a2396391.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
onclick={fetchingId(attributes.id)}
- did you forget the() =>
as inonclick={() => fetchingId(attributes.id)}
? Because you should actually pass a function and not the result of a function call. Otherwise, that would result in thefetchingId()
being called everytime the component is rendered.. See this FAQ on the React website, but that "pass a function" is not just in React - even in native JS, that's indeed how it works. – Sally CJ Commented Feb 10, 2021 at 13:12