新增、修改弹窗封装

FormModal

传统问题:
1、弹窗关闭时数据会清空,下一次打开数据还在
2、写一个弹窗、需要创建一堆变量,如 visible、loading、onClose、onOk…
3、开发者需要关注的副作用多,如打开/关闭弹窗、保存成功后刷新列表
4、编辑时回显数据逻辑、保存逻辑重复代码过多

解决方案

const FormModal = props => {
  const {onRef, onSave, onEcho, onSuccessCallback, children} = props;
  const [open, setOpen] = useState(false);
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);
  const [form] = Form.useForm();

  const onClose = () => {
    setOpen(false);
  };

  const valid = async () => {
    try {
      return await form.validateFields();
    } catch (e) {
      return false;
    }
  };

  const onOk = async () => {
    try {
      const formValue = await valid();

      if (!formValue) return;

      setLoading(true);
      const msg = await onSave(formValue, data);
      setLoading(false);

      message.success(msg || '操作成功');
      onClose();
      onSuccessCallback?.();
    } catch (e) {
      message.error(e?.message || '操作失败');
      setLoading(false);
    }
  };

  useImperativeHandle(onRef, () => ({
    open(value = null) {
      setData(value);
      setOpen(true);
    },
  }));

  /*
   * 回显加载数据
   *  */
  useEffect(() => {
    if (data && onEcho) {
      setLoading(true);
      onEcho(data)
        .then(value => {
          form.setFieldsValue(value);
        })
        .catch(e => {
          onClose();
          message.error(e?.message || '数据回显失败');
        })
        .finally(() => {
          setLoading(false);
        });
    }
  }, [data]);

  /*
   * 处理关闭弹窗副作用
   *  */
  useEffect(() => {
    if (!open) {
      form.resetFields();
      setData(null);
    }
  }, [open]);

  return (
    <Modal
      confirmLoading={loading}
      maskClosable={false}
      closable={false}
      open={open}
      onOk={onOk}
      onCancel={onClose}
      styles={{
        footer: {display: 'flex', justifyContent: 'center', gap: 30},
      }}>
      <Spin spinning={loading} tip="Loading">
        <Form form={form}>{children}</Form>
      </Spin>
    </Modal>
  );
};

使用

const BizModal = props => {
  const {onRef} = props;

  const onEcho = async params => {
    const res = await fetchData(params);
    return res.data;//需和表单字段一致
  };

  const onSave = async value => {
    const res = await fetchData(value);
    return res.msg;//返回成功提示信息即可
  };

  return (
    <FormModal onRef={onRef} onSave={onSave} onEcho={onEcho}>
      <Form.Item
        label="姓名"
        name="username"
        rules={[{required: true, message: '请输入姓名'}]}>
        <Input />
      </Form.Item>
    </FormModal>
  );
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值