MaterialUI封装全局Snackbar组件

最近在写点小项目,使用的是Material UI,这个UI库中没有类似Ant里可以全局使用的message组件,只有Snackbar消息条组件,但这种使用方式显然不够灵活,本来想试试自己造个轮子,但在翻看Material UI的文档时发现Snackbar组件文档最后有一个notistack方案来以更灵活的方式使用Snackbar组件。

本文章中使用依赖的信息

1
2
3
4
5
6
7
{
"notistack": "^1.0.6",
"@material-ui/core": "^4.11.3",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-scripts": "4.0.0"
}

相关文档

Material-UI Snackbar组件文档

notistack文档

开始使用

官方文档对于使用的说明很详细,这里就简单写写。

如果希望直接查看在线代码,请直接跳转至文末本篇代码

使用 notistack 时必须在外部包裹 SnackbarProvider 组件。

如果使用了Material UI 的 ThemeProvider 组件,则 SnackbarProvider 组件必须位于 ThemeProvider 组件内部。

1
2
3
4
5
import { SnackbarProvider } from 'notistack';

<SnackbarProvider>
<MyApp />
</SnackbarProvider>

SnackbarProvider 组件会传入两个方法:enqueueSnackbarcloseSnackbar

enqueueSnackbar 用于添加一个消息到队列中。官方文档说明

closeSnackbar 用于关闭消息。官方文档说明

官方Api文档

在React Class Component中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import React from "react";
import { withSnackbar, ProviderContext } from "notistack";
import { Button } from "@material-ui/core";

interface ClassDemoPropsType extends ProviderContext {}

class ClassDemo extends React.Component<ClassDemoPropsType> {
constructor(props: ClassDemoPropsType) {
super(props);
}
handleButtonClick = () => {
const { enqueueSnackbar } = this.props
// 使用enqueueSnackbar创建一条消息
enqueueSnackbar(
`类组件,点击按钮`,
{
variant: 'success'
});
};

render() {
return (
<Button
variant="contained"
color="primary"
onClick={this.handleButtonClick}
>
类组件中触发
</Button>
);
}
}

// 注入snackbar
export default withSnackbar(ClassDemo);

在React Function Component中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { Button } from "@material-ui/core";
import { useSnackbar } from "notistack";

const FunctionDemo = () => {
const { enqueueSnackbar } = useSnackbar();

const buttonClick = () => {
enqueueSnackbar(`函数式组件,点击按钮`, {
variant: 'success'
});
};
return (
<Button variant="contained" color="primary" onClick={buttonClick}>
函数式组件中触发
</Button>
);
};

export default FunctionDemo;

封装 SnackbarProvider 组件

可以将 SnackbarProvider 组件封装一次,免去后续直接修改根组件文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { SnackbarProvider } from "notistack";
import { SnackbarOrigin } from "@material-ui/core";

// 最大数量
const MAX_SNACK = 3;
// 自动隐藏时间,单位毫秒
const AUTO_HIDE_DURATION = 3000;
// 消息条位置
const POSITION: SnackbarOrigin = {
vertical: "top",
horizontal: "right"
};

export default function NotistackWrapper({ children }) {
return (
<SnackbarProvider
maxSnack={MAX_SNACK}
autoHideDuration={AUTO_HIDE_DURATION}
anchorOrigin={POSITION}
>
{children}
</SnackbarProvider>
);
}

在根组件使用 NotistackWrapper 组件替代之前未封装的 SnackbarProvider 组件。

本篇代码