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

React表单提交按钮加载态实现及弹窗关闭文本闪现问题咨询

问题原因

你使用的Material UI Dialog 组件默认带有退出过渡动画,调用close()后弹窗不会立刻从DOM中移除,会保留数百毫秒执行关闭动画。你当前的代码逻辑是close()执行后马上同步调用setLoading(false),状态更新早于动画结束,就会出现按钮文本短暂重现的问题。

解决方案

推荐通过监听弹窗打开状态重置loading,避免在关闭动画过程中修改按钮状态:

  1. 新增useEffect监听弹窗open属性,每次弹窗打开时自动重置loading为false
  2. 移除请求成功回调中的setLoading(false)逻辑,保证关闭动画期间按钮始终保持加载状态

修改后的核心代码如下:

export const NewClientDialog = (props: INewClientDialogProps) => {
  const {open, close} = props;
  const [fn, setFn] = useState("");
  const [ln, setLn] = useState("");
  const [email, setEmail] = useState("");
  const [pn, setPn] = useState("");
  const [newUser, setNewUser] = useState<INewClientProps>();
  const [loading, setLoading] = useState(false);

  // 每次弹窗打开时重置loading状态
  useEffect(() => {
    if (open) {
      setLoading(false);
    }
  }, [open]);

  useEffect(() => {
    const newClient: INewClientProps = {
      firstName: fn,
      lastName: ln,
      email: email,
      phoneNumber: pn
    }
    setNewUser(newClient)
  }, [fn, ln, email, pn])
  
  const onAddClient = () => {
    setLoading(true)
    createNewClient(newUser)
      .then(() => close())
    // 移除原来的setLoading(false)逻辑
  }

  const AddClientButton = () => {
    const contents = loading ? <CircularProgress /> : <div>Create new client</div>
    return (
      <Button onClick={() => onAddClient()}>
        {contents}
      </Button>
    );
  }

  return (
    <div>
      <Dialog onClose={close} open={open}>
        <TextField label="First name" onChange={(value) => setFn(value.target.value)}/>
        <TextField label="Last name" onChange={(value) => setLn(value.target.value)}/>
        <TextField label="Email address" onChange={(value) => setEmail(value.target.value)}/>
        <TextField label="Phone number" onChange={(value) => setPn(value.target.value)}/>
        <AddClientButton />
      </Dialog>
    </div>
  )
}
备选方案

你也可以用Dialog组件自带的onExited回调实现同样效果,该回调会在弹窗关闭动画完全结束、组件从DOM中移除后触发:

<Dialog 
  onClose={close} 
  open={open}
  onExited={() => setLoading(false)}
>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 00:18:05