Closed lencx closed 1 year ago
Confirm 布局基本是固定形式,可以通过Modal自定义布局
@stbui Modal
是组件式调用,Confirm
是函数式调用,但是 函数式的 Confirm
却不支持自定义布局。改写或重新实现,相当于对 zarm
进行二次开发,因为这种需求在实际业务开发中,出现频率很高,所以希望官方可以支持。
@lencx 我也想过同样的问题... 确实暂时能想到需要使用 Modal 场景, 都是命令式的方式来控制 Model 的显示隐藏, And D 是支持 Confirm 自定义 content 的, 但之前使用时, 遇到过这个问题 https://github.com/ant-design/ant-design/issues/29291#issuecomment-775869367, 所以 不论改动成本, 即使 Modal.Confirm 支持了自定义 content 内容, 仍会有一些局限
后来做了一个折中的方案, 可以一起讨论下: https://gist.github.com/iShawnWang/95d40403870f27970d84f0a2395d46dc 大意是利用 Context + Hook, 命令式的统一管理 Modal 的显示隐藏和传参
这种情况是不是把 Confirm 的逻辑抽成一个 hooks 组件会更好点。
这种情况是不是把 Confirm 的逻辑抽成一个 hooks 组件会更好点。
可... 晚些我想想, 出个 useModal
示例一起讨论下
只控制显示隐藏的简单版
// useModal.tsx
import { useState, useCallback } from 'react';
import type { ModalProps } from 'antd';
export default (props?: ModalProps) => {
const [visible, setVisible] = useState(false);
const hide = useCallback(() => setVisible(false), []);
return [
useCallback(() => setVisible(true), []),
{
visible,
onCancel: hide,
...props,
},
hide,
] as const;
};
使用
import { Modal, Button } from 'antd';
import useModal from './useModal1';
export default function IndexPage() {
const [showXXXModal, modalProps] = useModal();
return (
<>
<Button
onClick={() => {
showXXXModal();
}}
>
emm
</Button>
<Modal {...modalProps}></Modal>
</>
);
}
补充:
[]
, 用户可以自定义显示隐藏 Modal 的方法名, 也可以不用 hide 方法
对比 :
const { show, hide, modalProps } = useModal()
---
const [ showXXXModal, modalProps ] = useModal()
2. 包装自己的 useModal
import useModal from 'useModal'
export default MyUseModal = (props?: Parameters
一个邪门歪道激进版
export const useModal2 = (props?: ModalProps) => {
const [visible, setVisible] = useState(false);
const hide = useCallback(() => setVisible(false), []);
const _Modal: React.FC<ModalProps> = memo((_props) => {
const { children, ...rest } = _props;
return (
<Modal visible={visible} onCancel={hide} {...props} {...rest}>
{children}
</Modal>
);
});
return [useCallback(() => setVisible(true), []), _Modal, hide] as const;
};
使用超方便
export default function IndexPage() {
const [showXXXModal, Modal] = useModal2();
return (
<>
<Button
onClick={() => {
showXXXModal();
}}
>
emm
</Button>
<Modal>111</Modal>
</>
);
}
非常好用... 暂时有个缺陷... hide 时没有动画,
useModal
的局限性:
function component
或 hook
中使用class
组件无法使用function
无法使用可以参考 React-Toastify:
import React from 'react';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
function App(){
const notify = () => toast("Wow so easy!");
return (
<div>
<button onClick={notify}>Notify!</button>
<ToastContainer />
</div>
);
}
实现思路:
ToastContainer
放在根容器中import { toast } from 'zarm';
toast
需要暴露的 API 可能需要思考一下import React from 'react';
import { ToastContainer, toast } from 'zarm';
function App(){
// type: info, warn, error, success, confirm ...
const notify = () => toast.confirm({
// content
// onCancel?
// onOk?
});
return (
<div>
<button onClick={notify}>Notify!</button>
<ToastContainer />
</div>
);
}
关键代码参考:
@lencx 只试用单例模式的情况使用吧。如果页面上存在多个,或者多级弹层呢?
多例会维护一个 id list
get 了... 需要简单泛用的静态方法 ~
需求背景
因需求要求,弹窗内的
确认 / 取消
按钮,与组件布局不一致时,需要重写Confirm
内的组件布局。解决方案
支持函数组件对
Confirm
重新布局,通过参数导出onOK
,onCancel
方法,供用户使用。