import { Switch, type SwitchProps } from 'antd'; import React, { useEffect, useState } from 'react'; interface AsyncSwitchProps extends Omit { // Execute the function asynchronously. If successful, the state will be switched. If failed, the state will remain unchanged. onAsyncChange: (checked: boolean) => Promise; // Standard onChange, automatically injected in Form mode onChange?: (checked: boolean) => void; // Form.Item binds the value attribute to value by default, and the value attribute of Switch is checked. You can modify the bound value property through valuePropName. /** */ value?: boolean; defaultChecked?: boolean; // Successfully/unsuccessfully hook onSuccess?: () => void; onError?: (err: any) => void; } const AsyncSwitch: React.FC = (props) => { const { value, defaultChecked, onChange, onAsyncChange, onSuccess, onError, disabled, ...rest } = props; // 1. Internal maintenance status, the initial value is checked first, followed by defaultChecked const [innerChecked, setInnerChecked] = useState( !!(value ?? defaultChecked), ); const [loading, setLoading] = useState(false); // 2. When the external checked changes (such as Form reset or external manual modification), synchronize the internal state useEffect(() => { if (value !== void 0) { setInnerChecked(value); } }, [value]); const handleChange = async (val: boolean) => { setLoading(true); try { // Execute asynchronous logic await onAsyncChange(val); // Processing after success: // If checked is not passed externally (uncontrolled mode), the internal state is updated if (value === void 0) { setInnerChecked(val); } // Trigger external onChange (if it is Form, Form takes over the status update) onChange?.(val); onSuccess?.(); } catch (error) { console.warn('AsyncSwitch Error:', error); onError?.(error); // Failure does nothing and leaves the Switch as is } finally { setLoading(false); } }; return ( ); }; export default AsyncSwitch;