React--使用Hook和Context创建全局提示框
做一个全局的提示框,是非常有必要的,在使用的地方直接调用,而非在每个页面都插入一个提示框组件,可以使用这种技术的还有modal、notfication、dialog、spinner。
创建应用 #
环境准备,安装node、npm 或 yarn
1
2
3
| npx create-react-app react-alert
cd react-alert
npm start
|
创建alert #
创建context文件
1
2
| mkdir src/context
touch src/context/alert-context.js
|
创建完成之后的目录
1
2
3
4
| src
├ ...
├── context
│ └── alert-context.js
|
文件创建好了之后,接下来就要往里填充内容,修改alert-context.js, 先导入依赖
1
| import React, { useState, createContext, useContext, useEffect } from "react";
|
创建context对象
1
| const AlertContext = createContext();
|
定义alert组件
1
2
3
4
5
6
7
8
9
10
| const Alert = ({ onClick }) => {
return (
<div className="alert-wrapper">
<div className="alert">
<div>提示信息</div>
<button onClick={onClick}>关闭</button>
</div>
</div>
);
};
|
创建context provider
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| const AlertProvider = (props) => {
const [isDisplaying, setIsDisplaying] = useState(false);
const show = () => setIsDisplaying(true);
const dismiss = () => setIsDisplaying(false);
const onClick = () => setIsDisplaying(false);
return (
<AlertContext.Provider value={{ show, dismiss }} {...props}>
{props.children}
{isDisplaying && <Alert onClick={onClick} />}
</AlertContext.Provider>
);
};
|
AlertProvider创建完成,一般我们会用其包裹应用入口组件,一般是<App />
。但是,使用前需要导出,现在我们创建一个自定义 hook,将外部使用到的内容导出
1
2
3
4
| const useAlert = () => {
return useContext(AlertContext);
};
export default { AlertContext, useAlert };
|
使用alert #
下面就是如何使用以上制作的组件,首先配置AlertProvider,修改index.js
1
2
3
4
5
6
7
8
| import { AlertProvider } from "./context/alert-context";
// ...
ReactDOM.render(
<AlertProvider>
<App />
</AlertProvider>,
document.getElementById("root")
);
|
然后,在需要显示提示框,也就是需要调用show,dismiss的地方引入userAlert,修改App.js,在其中添加一个测试按钮
1
2
3
4
5
6
| import { useAlert } from './context/alert-context';
// ...
const alert = useAlert();
const onClick = () => alert.show();
// ...
<button onClick={onClick}>提示</button>;
|
以上就是基本的创建和使用,接下来可以对alert进行一点改造,使其更加完善
补充,给show添加参数 #
如果想让alert更加灵活,我们需要在show函数添加params 参数,最终将params传入alert,参数内容可以是title、icon等信息,修改alert-context.js
1
2
3
4
5
6
7
8
9
| //...
const [params, setParams] = useState();
//...
const show = (params) => {
params && setParams(params);
setIsDisplaying(true);
};
// ...
{isDisplaying && <Alert onClick={onClick} {...params} />;}
|
补充,按ESC键,隐藏提示框 #
使用useEffect, 在组件挂载时绑定ESC键,组件卸载时移除键绑定,在alert组件添加
1
2
3
4
5
6
7
8
9
| useEffect(() => {
const bind = (e) => {
if (e.keyCode !== 27) return;
if (document.activeElement && ["INPUT", "SELECT"].includes(document.activeElement.tagName)) return;
onClick && onClick();
};
document.addEventListener("keyup", bind);
return () => document.removeEventListener("keyup", bind);
}, []);
|
至此,一个全局的提示框就处理好了,至于样式,每个应用的风格各不相同,可以自由发挥。