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

如何通过复用<Button/>组件处理多按钮的加载/禁用状态与点击逻辑

复用按钮组件实现单按钮加载、其余禁用的方案

核心思路是把加载状态的控制权从子组件收回到父组件,用唯一标识追踪当前加载中的按钮,让单个通用按钮组件根据这个标识自动判断自身状态,既减少代码冗余,又满足需求。

1. 定义通用按钮组件

创建可复用的<ApiButton>组件,通过接收props来区分不同按钮的状态和行为:

import { Button } from 'your-ui-library'; // 替换为你使用的UI库(如Antd、MUI)

const ApiButton = ({ buttonKey, loadingKey, onClick, children }) => {
  const isLoading = loadingKey === buttonKey;
  // 禁用规则:有按钮在加载且不是当前按钮,或当前按钮正在加载(防止重复点击)
  const isDisabled = !!loadingKey && !isLoading;

  const handleClick = async () => {
    await onClick();
  };

  return (
    <Button
      onClick={handleClick}
      loading={isLoading}
      disabled={isDisabled || isLoading}
    >
      {isLoading ? '加载中...' : children}
    </Button>
  );
};

export default ApiButton;

2. 父组件中使用通用按钮

父组件维护全局加载状态,给每个按钮分配唯一标识,并传入对应的API请求逻辑:

import { useState } from 'react';
import ApiButton from './ApiButton';

const ParentComponent = () => {
  // 记录当前正在加载的按钮标识,初始为null表示无加载状态
  const [loadingButtonKey, setLoadingButtonKey] = useState(null);

  // 模拟接口请求1
  const fetchData1 = async () => {
    setLoadingButtonKey('btn1');
    try {
      await new Promise(resolve => setTimeout(resolve, 2000)); // 模拟接口延迟
      console.log('接口1请求完成');
    } catch (err) {
      console.error('接口1请求失败', err);
    } finally {
      setLoadingButtonKey(null); // 请求结束后重置状态
    }
  };

  // 模拟接口请求2
  const fetchData2 = async () => {
    setLoadingButtonKey('btn2');
    try {
      await new Promise(resolve => setTimeout(resolve, 2000));
      console.log('接口2请求完成');
    } catch (err) {
      console.error('接口2请求失败', err);
    } finally {
      setLoadingButtonKey(null);
    }
  };

  return (
    <div style={{ gap: '10px', display: 'flex', padding: '20px' }}>
      <ApiButton buttonKey="btn1" loadingKey={loadingButtonKey} onClick={fetchData1}>
        调用接口1
      </ApiButton>
      <ApiButton buttonKey="btn2" loadingKey={loadingButtonKey} onClick={fetchData2}>
        调用接口2
      </ApiButton>
      {/* 新增按钮只需添加唯一buttonKey和对应API函数即可 */}
    </div>
  );
};

export default ParentComponent;

方案优势

  • 完全复用单个按钮组件,新增按钮无需创建新组件,大幅减少冗余代码
  • 加载状态统一在父组件管理,避免子组件状态分散导致的同步问题
  • 禁用和加载逻辑集中在通用组件,后续修改只需维护一处代码

内容的提问来源于stack exchange,提问作者nikkbh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 01:05:28