fix toast

This commit is contained in:
Pig Fang 2020-06-23 15:37:18 +08:00
parent 56ec01f32a
commit 7a78c612bf
3 changed files with 43 additions and 15 deletions

View File

@ -33,14 +33,10 @@ const Toast: React.FC<Props> = (props) => {
const [show, setShow] = useState(false)
useEffect(() => {
const id1 = setTimeout(() => setShow(true), 100)
const id2 = setTimeout(() => setShow(false), 3000)
const id3 = setTimeout(props.onClose, 3100)
const timer = setTimeout(() => setShow(true), 100)
return () => {
clearTimeout(id1)
clearTimeout(id2)
clearTimeout(id3)
clearTimeout(timer)
}
}, [props.onClose])

View File

@ -13,12 +13,20 @@ const CLEAR_EVENT = Symbol('clear')
export const ToastContainer: React.FC = () => {
const [queue, setQueue] = useState<ToastQueue>([])
const handleClose = (id: string) => {
setQueue((queue) => queue.filter((el) => el.id !== id))
}
useEffect(() => {
const off1 = emitter.on(TOAST_EVENT, (toast: QueueElement) => {
setQueue((queue) => {
queue.push(toast)
return queue.slice()
})
setTimeout(() => {
handleClose(toast.id)
}, 3100)
})
const off2 = emitter.on(CLEAR_EVENT, () => setQueue([]))
@ -28,12 +36,9 @@ export const ToastContainer: React.FC = () => {
}
}, [])
const handleClose = (id: string) => {
setQueue((queue) => queue.filter((el) => el.id !== id))
}
return (
<>
{queue.length}
{queue.map((el, i) => (
<ToastBox
key={el.id}
@ -49,11 +54,16 @@ export const ToastContainer: React.FC = () => {
}
export class Toast {
constructor() {
const container = document.createElement('div')
document.body.appendChild(container)
private container: HTMLDivElement
ReactDOM.render(<ToastContainer />, container)
constructor() {
this.container = document.createElement('div')
document.body.appendChild(this.container)
/* istanbul ignore next */
if (process.env.NODE_ENV !== 'test') {
ReactDOM.render(<ToastContainer />, this.container)
}
}
success(message: string) {
@ -75,4 +85,12 @@ export class Toast {
clear() {
emitter.emit(CLEAR_EVENT)
}
dispose() {
/* istanbul ignore next */
if (process.env.NODE_ENV !== 'test') {
ReactDOM.unmountComponentAtNode(this.container)
}
this.container.remove()
}
}

View File

@ -1,5 +1,5 @@
import React from 'react'
import { render } from '@testing-library/react'
import { render, fireEvent, screen } from '@testing-library/react'
import { Toast, ToastContainer } from '@/scripts/toast'
test('"Toast" class', () => {
@ -25,6 +25,7 @@ test('"Toast" class', () => {
)
jest.runAllTimers()
toast.dispose()
})
test('clear toasts', () => {
@ -36,4 +37,17 @@ test('clear toasts', () => {
toast.clear()
expect(document.querySelectorAll('.alert')).toHaveLength(0)
toast.dispose()
})
test('close toast manually', () => {
render(<ToastContainer />)
const toast = new Toast()
toast.success('success')
fireEvent.click(screen.getByText('×'))
expect(document.querySelectorAll('.alert')).toHaveLength(0)
toast.dispose()
})