Skip to content

Commit

Permalink
fix: toast가 사라지지않는 문제 해결
Browse files Browse the repository at this point in the history
  • Loading branch information
eunbae0 committed Mar 2, 2024
1 parent 82c59ea commit a46626f
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 26 deletions.
25 changes: 23 additions & 2 deletions components/common/Toast/Toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ import * as S from './Toast.style'
import Icon from '../Icon/Icon'

import { toastMessage, ToastMessageEnum } from '@/lib/constant/toastMessage'
import { memo, useEffect } from 'react'
import { ToastListType } from '@/lib/provider/ToastProvider'

const DEFAULT_AUTO_CLOSE_TIME = 3 * 1000

export type ToastProps = {
id: number
message: ToastMessageEnum
/** label 사용시 message: 'none'을 지정한 다음 사용해주세요.
* @example
Expand All @@ -12,10 +17,26 @@ export type ToastProps = {
* ```
*/
label?: string
autoClose?: number
handleClickDelete: () => void
setToast: React.Dispatch<React.SetStateAction<ToastListType[]>>
}

const Toast = ({ message, label, handleClickDelete }: ToastProps) => {
const Toast = ({
id,
message,
label,
autoClose = DEFAULT_AUTO_CLOSE_TIME,
handleClickDelete,
setToast,
}: ToastProps) => {
useEffect(() => {
const timeout = setTimeout(() => {
setToast((prev) => prev.filter((item) => (item.id === id ? null : item)))
}, autoClose)
return () => clearTimeout(timeout)
}, [])

return (
<S.Container>
<S.LeftWrapper>
Expand All @@ -29,4 +50,4 @@ const Toast = ({ message, label, handleClickDelete }: ToastProps) => {
)
}

export default Toast
export default memo(Toast)
11 changes: 9 additions & 2 deletions hooks/useToastMessage.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import { useContext } from 'react'
import { ToastContext } from '@/lib/provider/ToastProvider'

/**
* @example
* ```tsx
* const { openToast } = useToastMessage()
* openToast({ message: 'common' })
* ```
*/
const useToastMessage = () => {
const { createToast, deleteToast } = useContext(ToastContext)
return { createToast, deleteToast }
const { createToast } = useContext(ToastContext)
return { openToast: createToast }
}

export default useToastMessage
38 changes: 16 additions & 22 deletions lib/provider/ToastProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,25 @@ import styled from '@emotion/styled'

import Toast, { ToastProps } from '@/components/common/Toast/Toast'

type ToastListType = { id: number; timeout: ReturnType<typeof setTimeout> } & Omit<ToastProps, 'handleClickDelete'>
export type ToastListType = Omit<ToastProps, 'handleClickDelete' | 'setToast'>
export type createToastOptions = Omit<ToastListType, 'id'>

export const ToastContext = createContext({
createToast: () => {},
deleteToast: (id: ToastListType['id']) => {},
createToast: (obj: createToastOptions) => {},
})

function ToastProvider({ children }: PropsWithChildren) {
const [toastList, setToast] = useState<Array<ToastListType>>([])

const createToast = () => {
const createToast = ({ message, label, autoClose }: createToastOptions) => {
setToast((prev) => {
console.log('1')

return [
...prev,
{
id: Math.random(),
message: 'common',
timeout: setTimeout(() => {
// return 'finish'
setToast((prev) => {
const prevArray = prev
prevArray.shift()
console.log('2')
return prevArray
})
}, 3000),
message,
label,
autoClose,
},
]
})
Expand All @@ -40,18 +31,21 @@ function ToastProvider({ children }: PropsWithChildren) {
setToast((prev) => prev.filter((item) => (item.id === id ? null : item)))
}

const value = useMemo(() => ({ createToast, deleteToast }), [createToast, deleteToast])

useEffect(() => {
console.log(toastList)
}, [toastList])
const value = useMemo(() => ({ createToast }), [createToast])

return (
<ToastContext.Provider value={value}>
{children}
<S.ToastListContainer>
{toastList.reverse().map((item) => (
<Toast key={item.id} message={item.message} handleClickDelete={() => deleteToast(item.id)} />
<Toast
key={item.id}
id={item.id}
message={item.message}
autoClose={item.autoClose}
setToast={setToast}
handleClickDelete={() => deleteToast(item.id)}
/>
))}
</S.ToastListContainer>
</ToastContext.Provider>
Expand Down

0 comments on commit a46626f

Please sign in to comment.