使用mui的​​Snackbar​

思路 暴露一个 ref 需要通知的时候调用 组件暴露的方法

import {
ReactElement,
useState,
createRef,
useImperativeHandle,
useCallback,
useRef,
useEffect,
} from "react";
import { Alert, AlertColor, Snackbar, SnackbarOrigin } from "@mui/material";

interface IOpen {
message: string;
type?: AlertColor;
origin?: SnackbarOrigin;
}

interface INoticRef {
open: (p: IOpen) => void;
close: () => void;
}

export const NoticeRef = createRef<null | INoticRef>();

const Notice = (): ReactElement => {
const [state, setState] = useState(false);
const time = useRef<any>(null);
const [message, setMessage] = useState("");
const [type, setType] = useState<AlertColor>("info");
const [origin, setOrigin] = useState<SnackbarOrigin>({
vertical: "bottom",
horizontal: "right",
});
//! Bug Snackbar 设置自动隐藏 功能需要提供 onClose 事件 但是点击页面一下就会触发onClose事件 无奈自己实现
useEffect(() => {
if (state) {
time.current = setTimeout(() => {
setState(false);
}, 3000);
}
return () => {
clearTimeout(time.current);
time.current = null;
};
}, [state, type, origin]);

const close: any = useCallback(() => setState(false), []);

const open = useCallback(({ message, type, origin }: IOpen) => {
type && setType(type);
origin && setOrigin(origin);
setMessage(message);
setState(true);
}, []);

useImperativeHandle(NoticeRef, () => ({ close, open }), [close, open]);

return (
<Snackbar message={message} open={state} anchorOrigin={origin}>
<Alert onClose={close} severity={type}>
{message}
</Alert>
</Snackbar>
);
};

export default Notice;

注入

import Notice from "./components/Notice";

function App() {
return (
<ThemeProvider theme={xxx}>
<Notice />
</ThemeProvider>
);
}

使用

import { NoticeRef } from "./components/Notice";

<Button
onClick={() => {
NoticeRef.current?.open({
message: "右下",
type: "warning",
origin: { horizontal: "right", vertical: "bottom" },
});
}}
variant="contained"
>
右下
</Button>