@rxflow/base
Version:
BaseFlow - 核心 Flow 组件库
86 lines (81 loc) • 2.08 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.LoadingButton = void 0;
var _ahooks = require("ahooks");
var _antd = require("antd");
var _react = require("react");
var _jsxRuntime = require("react/jsx-runtime");
/*
* @author: yanxianliang
* @date: 2025-05-23 15:19
* @desc: Loading Button
*
* 支持业务防抖
*
* Copyright (c) 2025 by yanxianliang, All Rights Reserved.
*/
/**
* LoadingButton 组件
* - 支持 loading 状态受控/非受控
* - 支持点击防抖(防止重复点击)
* - 支持异步 onClick
*
* @param props
* onClick: 点击事件,支持返回 Promise
* throttle: 防抖间隔,默认 300ms
*/
const LoadingButton = props => {
const lockRef = (0, _react.useRef)(false); // 点击锁,loading 无法解决鼠标连击问题
const throttle = props.throttle ?? 300;
/**
* loading 状态受控/非受控
*/
const [loading, setLoading] = (0, _ahooks.useControllableValue)(props, {
valuePropName: 'loading',
trigger: 'onLoadingChange'
});
/**
* 包装点击事件,支持防抖和 loading
*/
const onButtonClick = (0, _ahooks.useMemoizedFn)(e => {
if (lockRef.current) {
return; // 防抖拦截
}
lockRef.current = true;
const result = props.onClick?.(e);
if (result && result instanceof Promise) {
(async () => {
setLoading(true);
try {
await result;
// eslint-disable-next-line @typescript-eslint/no-shadow
} catch (e) {
/* empty */
} finally {
setLoading(false);
setTimeout(() => {
lockRef.current = false;
}, throttle);
}
})();
} else {
setTimeout(() => {
/**
* 纯前端交互的,进行前端防抖
*/
lockRef.current = false;
}, throttle);
}
});
/**
* 渲染按钮
*/
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Button, {
...props,
loading: loading,
onClick: onButtonClick
});
};
exports.LoadingButton = LoadingButton;