WordPress技术求助:如何阻止Gutenberg区块触发重复GET请求?
解决Gutenberg区块中WooCommerce API重复请求及按钮触发失效问题
你已经摸到了问题的核心,我来帮你把整个解决方案梳理清楚,彻底解决这两个问题:
1. 按钮点击事件的正确绑定
你最初的重复请求和触发失效,本质都是函数执行时机的错误:
- 写
onclick={fetchingId(attributes.id)}时,这会在组件每次渲染(比如输入框内容变化)时立即执行fetchingId,而不是点击按钮时才执行——这就是为啥点输入框也会发请求的原因。 - 改成
onclick={fetchingId}后,虽然传递了函数引用,但没有传id参数,函数执行时拿不到产品ID,自然调用失败。
正确写法(用Gutenberg Button组件)
记住两个关键细节:
- React事件用驼峰式的
onClick,而非原生的onclick - 用箭头函数包裹,把
attributes.id作为参数传递给fetchingId
<Button isPrimary className='fetch-product' onClick={() => fetchingId(attributes.id)} > Chercher un produit </Button>
2. 优化API请求逻辑
另外可以把fetchingId的异步写法统一,避免async/await和.then/.catch混用的冗余,同时增加ID非空判断防止无效请求:
const fetchingId = async (id) => { // 先判断ID是否有效,避免无意义的API调用 if (!id) return; try { const response = await WooCommerce.get(`products/${id}`); console.log(response.data); // 合并setAttributes调用,减少组件渲染次数 setAttributes({ price: response.data.price, name: response.data.name }); } catch (error) { console.log(error.response.data); setAttributes({ price: '', name: '' }); } }
3. 关于useEffect的补充说明
如果之后你想改成输入框修改后自动触发请求,而非点击按钮,那确实需要用useEffect监听id的变化,避免重复请求:
import { useEffect } from '@wordpress/element'; // 在edit函数内部添加 useEffect(() => { // 仅当ID存在且变化时触发请求 if (attributes.id) { const fetchProduct = async () => { try { const response = await WooCommerce.get(`products/${attributes.id}`); setAttributes({ price: response.data.price, name: response.data.name }); } catch (error) { setAttributes({ price: '', name: '' }); } }; fetchProduct(); } }, [attributes.id]); // 依赖项:仅当id变化时执行
但根据你的需求,点击按钮触发的话,第一种方案就完全够用了。
完整修改后的edit函数示例
import { useBlockProps, TextControl, Button } from '@wordpress/block-editor'; const edit = ({ attributes, setAttributes }) => { const blockProps = useBlockProps(); const fetchingId = async (id) => { if (!id) return; try { const response = await WooCommerce.get(`products/${id}`); console.log(response.data); setAttributes({ price: response.data.price, name: response.data.name }); } catch (error) { console.log(error.response.data); setAttributes({ price: '', name: '' }); } }; return ( <div {...blockProps}> <div className="wrapper-input"> <TextControl label={__('ID du Produit', 'ingredient-unique')} value={attributes.id} onChange={(val) => setAttributes({ id: val })} className='control-id' /> </div> <Button isPrimary className='fetch-product' onClick={() => fetchingId(attributes.id)} > Chercher un produit </Button> {/* 可选:添加产品信息展示区域 */} {attributes.name && ( <div className="product-info"> <h3>{attributes.name}</h3> <p>Prix: {attributes.price}</p> </div> )} </div> ); };
额外注意事项
- 确保
WooCommerce实例已正确初始化,API密钥和权限配置无误 - 合并
setAttributes调用,避免多次触发组件不必要的重渲染 - 始终添加参数合法性判断,减少无效的API请求
内容的提问来源于stack exchange,提问作者JAGENI Nat
相关产品推荐
相关产品推荐

