You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 07:09:10