antd有個Notification組件用于全局通知提醒, 現(xiàn)在用react實現(xiàn)一個相同的組件魔市。
image.png
思考這個組件:
- 全局提示 ,即在任何地方都可以通過方法調(diào)用
- 如何將組件渲染到頁面上
定義方法名稱為toast,可以知道在使用時袁梗,只要調(diào)用toast() 就會在頁面上出現(xiàn)提示觉吭,幾秒后提示消失腾供,也可以手動關閉
該類組件一般會有一些像success,error ,warning的分類伴鳖,所以調(diào)用的形式是toast.success('提示文案')
一节值、第一步:dom實現(xiàn)
const dispatchToast = (toast, type) => {
let item = { toast, type }
if (containerDomNode) {
//當containerDomNode存在時,不重新createElement
globalControl.add(item)
} else {
containerDomNode = document.createElement('div')
document.body.appendChild(containerDomNode)
//ToastContainer是提示組件
ReactDOM.render(<ToastContainer initToast={item} />, containerDomNode)
}
}
export default {
success: v => dispatchToast(v, 'success'),
error: v => dispatchToast(v, 'error'),
warning: v => dispatchToast(v, 'warning')
}
globalControl是一個全局的控制器榜聂, 用于控制組件的數(shù)量
containerDomNode是一個全局變量搞疗,是用于放置組件的面板
第二步:實現(xiàn)ToastContainer
const ToastContainer = ({ initToast }) => {
const [queue] = useQueue()
useEffect(() => {
if (initToast) {
globalControl.add(initToast)
}
}, [])
return (
<div className={styles.container}>
{queue.map(el => (
<p
className={`${styles.item} ${styles[el.type]}`}
key={el._tid}
onClick={() => globalControl.rm(el._tid)}
>
{el.content}
</p>
))}
</div>
)
}
queue就是toast的數(shù)量
第三步:自定義useQueue勾子
// toast標識符計數(shù)器
let tid = 0
let globalControl = {}
let containerDomNode = undefined
// 默認配置
const defaultOption = {
duration: 3000,
content: 'this is default content!'
}
const useQueue = () => {
const [queue, setQueue] = useState([])
const add = (item = {}) => {
const _tid = getName()
item = Object.assign({ _tid }, defaultOption, item)
setQueue(v => [...v, item])
setTimeout(() => rm(item._tid), item.duration)
}
const rm = tid => {
setQueue(v => v.filter(el => el._tid !== tid))
}
const getName = () => `__toast_id_${++tid}`
const control = {
add,
rm
}
globalControl = control
return [queue]
}