Toast ์ ์šฉ๊ธฐ

2024. 12. 10. 20:01ยทWhat I Learn

 

๊ธฐํš ๋‹จ๊ณ„์—์„œ PM๋‹˜๊ณผ ๋””์ž์ด๋„ˆ๋‹˜๊ณผ ํ•จ๊ป˜ ์ƒ์˜ํ•  ๋•Œ๋ถ€ํ„ฐ ์‚ฌ์šฉ์ž์˜ ์ž…์žฅ์—์„œ ํ”Œ๋žซํผ์—์„œ ์‚ฌ์šฉ์„ฑ์ด ์ข‹๊ฒŒ ๋А๊ปด์ง€๊ฒŒ ํ•˜๋ ค๋ฉด ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์„๊นŒ๋ฅผ ๋งŽ์ด ๊ณ ๋ฏผํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

๊ทธ ๊ณผ์ •์—์„œ ์œ ์ €๊ฐ€ ์–ด๋ ต๊ฒŒ ๋А๊ปด์งˆ ์ˆ˜ ์žˆ์„ ๋ฒ•ํ•œ ๋ถ€๋ถ„์—์„œ ํˆดํŒ์ด๋‚˜ ํ† ์ŠคํŠธ๋ฅผ ์ด์šฉํ•ด์„œ ๋ฐฉ๋ฒ•์„ ์ ์ ˆํžˆ ์ œ์‹œํ•ด์ฃผ๊ธฐ๋กœ ํ–ˆ๋Š”๋ฐ, ๋ฌธ์ œ๋Š” ๋‹ค๋ฅธ ๋ถ„๋“ค์ด ์Šค๋‚ต๋ฐ”์™€ ํ† ์ŠคํŠธ, ํˆดํŒ ๋ชจ๋‘ ํ˜ผ์šฉํ•ด์„œ ์›Œ๋“œ๋ฅผ ์“ฐ๋‹ค๋ณด๋‹ˆ ๋‹ค ๋ชจ๋ฅด๋Š” ๋‚˜๋Š”.. ์ด๊ฒŒ ๋ญ์ง€ ๐Ÿ˜ฑ ??! ์ƒํƒœ๊ฐ€ ๋˜์—ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๊ณต๋ถ€ํ–ˆ๋‹ค.....

 

์‚ฌ์šฉ์ž ์ƒํ˜ธ์ž‘์šฉ์œผ๋กœ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋Š” ์•Œ๋ฆผ์ฐฝ์˜ ์ข…๋ฅ˜๋Š” ์ด์ •๋„๋กœ ์ฐพ์•„๋ดค๋‹ค.

  ์„ค๋ช… ์‚ฌ์šฉ ์˜ˆ์‹œ
Dialog ์‚ฌ์šฉ์ž์˜ ์ค‘์š”ํ•œ ์ƒํ˜ธ์ž‘์šฉ์„ ์œ„ํ•œ ์›น ํŽ˜์ด์ง€ ๋‚ด๋ถ€์—์„œ ์ƒ์„ฑ๋˜๋Š” ์ปดํฌ๋„ŒํŠธ.
์‚ฌ์šฉ์ž๊ฐ€ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์ „๊นŒ์ง€๋Š” ์‚ฌ๋ผ์ง€์ง€ ์•Š๋Š”๋‹ค.
์ •๋ณด ์ž…๋ ฅ, ์‚ญ์ œ ํ™•์ธ
Toast ์‚ฌ์šฉ์ž์˜ ๋™์ž‘์— ์˜ํ•œ ํ”ผ๋“œ๋ฐฑ์„ ๊ฐ„๋‹จํ•œ ui๋กœ ๋ณด์—ฌ์ฃผ๊ณ  ์‚ฌ๋ผ์ง€๋Š” ์ž‘์€ pop-up ํ˜•ํƒœ์˜ ๋ฐ”. ์ „์†ก ์™„๋ฃŒ, N๊ฐœ ์ด์ƒ์€ ์„ ํƒํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค
Snackbar Toast์˜ ๊ธฐ๋Šฅ์„ ๊ฐ–์ถ”๊ณ , ์ถ”๊ฐ€์ ์ธ ์ƒํ˜ธ์ž‘์šฉ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ์•ก์…˜ ๊ธฐ๋Šฅ (๋ฒ„ํŠผ) ์ด ์žˆ๋Š” ๋ฐ”.  (์›น์‚ฌ์ดํŠธ ์ ‘๊ทผ์‹œ)
์ฟ ํ‚ค ์ •์ฑ… ์ผ๋ถ€ ์ฟ ํ‚ค ์ฐจ๋‹จํ•˜๊ธฐ ๋ชจ๋‘ ํ—ˆ์šฉ
Tooltip ํŠน์ • ์˜์—ญ์— ์ปค์„œ๋กœ hover์‹œ ๋‚˜ํƒ€๋‚˜๋Š” ํ•ด๋‹น ์˜์—ญ์— ๋Œ€ํ•œ ์ •๋ณด ๋ฐ•์Šค. ๋ฒ„ํŠผ ๊ธฐ๋Šฅ ์„ค๋ช…
Alert ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ฒฝ๊ณ ๋‚˜ ์ค‘์š”ํ•œ ์•Œ๋ฆผ์„ ์ „๋‹ฌํ•˜๋Š” ์‹œ์Šคํ…œ ๋˜๋Š” ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ๋ฐ•์Šค. ์˜ค๋ฅ˜ ๋ฉ”์„ธ์ง€

 

n๋…„๊ฐ„์˜ ์‡ผํ•‘๊ฒฝ๋ ฅ์œผ๋กœ ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์› ๋‹ค.

์ž๋ผ์—์„œ ๋‚˜์˜ค๋Š” ์ฟ ํ‚ค ํ—ˆ์šฉ ์ •์ฑ… ์–ด์ฉŒ๊ณ ๊ฐ€ ์Šค๋‚ต๋ฐ”๊ตฌ๋‚˜... ์›น์‚ฌ์ดํŠธ์—์„œ ์•Œ๋ฆผ ๋‚˜์™”๋‹ค๊ฐ€ ์ž๋™์œผ๋กœ ์‚ฌ๋ผ์ง€๋˜ ๊ฒŒ ํ† ์ŠคํŠธ์˜€๊ตฌ๋‚˜...

 

๊ทธ๋ ‡๊ฒŒ ๊ธฐํš์„ ๋งˆ์น˜๊ณ  ํ† ์ŠคํŠธ๋ฅผ ๋ฐ”๋กœ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ฐพ์•„๋ณด๋‹ˆ ๋Œ€๋ถ€๋ถ„ react-toastify, ํ˜น์€ react-hot-toast๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ๋„ react-hot-toast๋ฅผ ์‚ฌ์šฉํ•œ ์ด์œ ๋Š” react-toastify๊ฐ€ ์‚ฌ์šฉ๋ฅ ์ด ๋†’๊ธฐ๋Š” ํ–ˆ์ง€๋งŒ ๋‚˜์˜จ ๋””์ž์ธ์ด react-hot-toast์˜ ui์— ๋” ์ ํ•ฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด์—ˆ๋‹ค.

react-toastify๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•˜๋ฉด ์Šค๋‚ต๋ฐ”๋กœ ์ด์šฉํ•  ๋•Œ ๋” ์ ํ•ฉํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ, ์ดํ›„ ํ† ์ŠคํŠธ์˜ ๊ธฐ๋Šฅ์ด ํ™•์žฅ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์—†์–ด์„œ react-hot-toast๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค. 

 

์ฐพ์•„๋ณด๋‹ˆ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์ด๋‚˜ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋น„์Šทํ•ด์„œ, toastify๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•ด๋„ ์–ด๋ ต์ง€ ์•Š๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์œผ๋กœ ๋ณด์ธ๋‹ค. 

 

 

 

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ์œ„ ํŽ˜์ด์ง€์—์„œ <Toaster /> ์„ ์–ธํ•˜๊ณ  ํ† ์ŠคํŠธ๋ฅผ ๋ถ€๋ฅผ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ toast() ๋กœ ํ˜ธ์ถœํ•˜๋ฉด ๋œ๋‹ค. 

import { Toaster } from 'react-hot-toast'

export default function Page({
  params: { userId, type, messageId },
}: {
  params: { userId: string; type: MessageType; messageId: string }
}) {
  return (
    <div>
  //  <div> Header... </div>
      <ReactionPage messageType={type} userId={userId} messageId={messageId} />
      <Toaster
        position='bottom-center'
        containerStyle={{
          bottom: '100px',
        }}
      />
    </div>
  )
}

 

    toast('๋ฐ˜์‘์€ ์ตœ๋Œ€ 5๊ฐœ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์–ด์š”', {
          icon: (
            <Image
              src='/toast_alert.svg'
              alt='toast_alert'
              width={18}
              height={18}
            />
          ),
          style: {
            borderRadius: '16px',
            backgroundColor: '#474747',
            width: '100%',
            height: '56px',
            paddingLeft: '3.8rem',
            paddingRight: '3.2rem',
          },
        })

 

 

๊ทธ๋Ÿผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ui๊ฐ€ ๋‚˜์˜จ๋‹ค.

 

๊ทธ๋Ÿฐ๋ฐ ๊ฐฏ์ˆ˜ ์ œํ•œ์ฒ˜๋ฆฌ ์—†์ด ์ด๋ฒคํŠธ๋งŒ ๊ฑธ์–ด๋‘๋ฉด 

 

ใ…Žใ…Ž;; ์ด์ œ ์—ฌ๊ธฐ์— ํ† ์ŠคํŠธ ๊ฐฏ์ˆ˜ ์ œํ•œ์„ ๊ฑธ์–ด์ค€๋‹ค. 

 

์—ฌ๊ธฐ์„œ ๋” ์„ค์ •ํ•  ์กฐ๊ฑด์„ ์ •๋ฆฌํ•ด๋ณด๋ฉด 

- 5๊ฐœ ์ดˆ๊ณผ ์„ ํƒ๋˜๋ฉด ํ† ์ŠคํŠธ

- ํ™”๋ฉด์—๋Š” ์ตœ๋Œ€ 2๊ฐœ๊นŒ์ง€ ๋ณด์—ฌ์ง„๋‹ค.

- 5๊ฐœ ์„ ํƒ๋œ ์ƒํƒœ์—์„œ ์ด๋ฏธ ์„ ํƒ๋œ ๋…€์„์„ ๋ˆ„๋ฅด๋ฉด set์—์„œ delete๋งŒ ๋˜๊ณ  ํ† ์ŠคํŠธ์— ์˜ํ–ฅ์„ ๋ผ์น˜๋ฉด ์•ˆ๋œ๋‹ค.  

 

    const [selectedSet, setSelectedSet] = useState<Set<string>>(new Set())
    const [toastVisible, setToastVisible] = useState(false)

    const storedData = (templateId: string): Set<string> => {
      setToastVisible(false)
      setSelectedSet((prevSet) => {
        const newSet = new Set(prevSet)

        if (newSet.has(templateId)) {
          newSet.delete(templateId)
        } else {
          if (newSet.size < 5) {
            newSet.add(templateId)
          } else {
            setToastVisible(true)
          }
        }
        return newSet
      })

      return selectedSet
    }

    useEffect(() => {
      if (toastVisible) {
        toast('๋ฐ˜์‘์€ ์ตœ๋Œ€ 5๊ฐœ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์–ด์š”', {
          icon: (
            <Image
              src='/toast_alert.svg'
              alt='toast_alert'
              width={18}
              height={18}
            />
          ),
          style: {
            borderRadius: '16px',
            backgroundColor: '#474747',
            width: '100%',
            height: '56px',
            paddingLeft: '3.8rem',
            paddingRight: '3.2rem',
          },
        })
      } else {
        setToastVisible(false)
      }
    }, [selectedSet, toastVisible])

 

์„ ํƒ๋œ ์ด๋ชจ์ง€๋“ค์„ set ํƒ€์ž…์œผ๋กœ ๊ฑธ์–ด์„œ ์‚ฌ์ด์ฆˆ๋กœ ๊ฐฏ์ˆ˜๋ฅผ ํ™•์ธํ–ˆ๊ณ , ์ดํ›„ ์ด set ๋ฐ์ดํ„ฐ๋“ค์„ postํ•  ๋•Œ๋Š” array๋กœ ๋ณ€ํ™˜ํ•ด์„œ ๋ณด๋ƒˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ๊ณ ๋ฏผ์ด์—ˆ๋˜ ๊ฒƒ์ด ์˜ˆ์ƒ ๋˜๋Š” ๋™์ž‘์€ ํ† ์ŠคํŠธ๊ฐ€ ํ•˜๋‚˜์”ฉ ๋œจ๋Š” ๊ฑฐ์˜€๋Š”๋ฐ 2๊ฐœ์”ฉ ๋œจ๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.

 

์ฝ˜์†”๋กœ ์ฐ์–ด๋ณด๋‹ˆ ๋ฆฌ์•กํŠธ์˜ ๋ Œ๋”๋ง ๋•Œ๋ฌธ์— ์ผ์–ด๋‚˜๋Š” ๊ฒƒ ๊ฐ™์•˜๋Š”๋ฐ, ์ƒ์œ„ ํŽ˜์ด์ง€์—์„œ <Toaster /> ํ† ์ŠคํŠธ์˜ ๋ฆฌ๋ฏธํŠธ ๊ฐฏ์ˆ˜๋ฅผ ์„ค์ •ํ•˜๊ณ  useEffect๋กœ ์ด ๋ฆฌ๋ฏธํŠธ๋ฅผ ๋„˜์–ด๊ฐ€๋Š” ํ† ์ŠคํŠธ๋“ค์— ๋Œ€ํ•ด toast.dismiss()๋ฅผ ์ˆ˜ํ–‰ํ•˜๋„๋ก ํ–ˆ๋‹ค.

dismiss ๋ฉ”์†Œ๋“œ๋Š” react-hot-toast docs์—์„œ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ์—ˆ๋‹ค. 

 

๊ทธ๋ฆฌ๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์ด toastOptions์— style๋กœ ์„ค์ •ํ•˜๋ฉด ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ ์šฉ๋˜๋Š” ํ† ์ŠคํŠธ์˜ ์ค‘๋ณต๋˜๋Š” ์Šคํƒ€์ผ๋“ค์„ ํ•œ๋ฒˆ์— ์ ์šฉ์‹œํ‚ฌ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

import toast, { Toaster, useToasterStore } from 'react-hot-toast'

export default function Page({
  params: { userId, type, messageId },
}: {
  params: { userId: string; type: MessageType; messageId: string }
}) {
  const router = useRouter()
  const { toasts } = useToasterStore()
  const toastLimit = 1

  useEffect(() => {
    const visibleToasts = toasts.filter((t) => t.visible)
    if (visibleToasts.length > toastLimit) {
      visibleToasts.slice(toastLimit).forEach((t) => toast.dismiss(t.id))
    }
  }, [toasts])

  return (
    <div>
    ...
      <Toaster
        position='bottom-center'
        containerStyle={{
          bottom: '100px',
        }}
        toastOptions={{ //  <- !!
          style: {
            borderRadius: '16px',
            backgroundColor: '#474747',
            width: '100%',
            height: '56px',
          },
        }}
      />
    </div>
  )
}

 

 

์ ์šฉ ์˜์ƒ > https://youtu.be/X5MTjK7DrEc

 

 

'What I Learn' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Lottie๋กœ ์ชฝ์ง€ ์ธ๋„ค์ผ์— ์ ์šฉํ•˜๊ธฐ  (0) 2024.12.10
TanStack Query์™€ ํ•จ๊ป˜ ๊ตฌํ˜„ํ•œ cursor ๋ฐฉ์‹์˜ ๋ฌดํ•œ ์Šคํฌ๋กค  (1) 2024.12.10
scroll ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•œ ๋ฌดํ•œ ์Šคํฌ๋กค ๊ตฌํ˜„  (1) 2024.10.27
Next.js ๋ณ‘๋ ฌ ๋ผ์šฐํŒ… & ๊ฒฝ๋กœ ๊ฐ€๋กœ์ฑ„๊ธฐ๋ฅผ ํ†ตํ•œ ๋ชจ๋‹ฌ ํŽ˜์ด์ง€ ๊ตฌํ˜„  (1) 2024.10.27
OSSCA: LLM ์กฐ์‚ฌ, Continue ๋ถ„์„ ๋ฐ ์ •๋ฆฌ  (8) 2024.10.24
'What I Learn' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • Lottie๋กœ ์ชฝ์ง€ ์ธ๋„ค์ผ์— ์ ์šฉํ•˜๊ธฐ
  • TanStack Query์™€ ํ•จ๊ป˜ ๊ตฌํ˜„ํ•œ cursor ๋ฐฉ์‹์˜ ๋ฌดํ•œ ์Šคํฌ๋กค
  • scroll ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•œ ๋ฌดํ•œ ์Šคํฌ๋กค ๊ตฌํ˜„
  • Next.js ๋ณ‘๋ ฌ ๋ผ์šฐํŒ… & ๊ฒฝ๋กœ ๊ฐ€๋กœ์ฑ„๊ธฐ๋ฅผ ํ†ตํ•œ ๋ชจ๋‹ฌ ํŽ˜์ด์ง€ ๊ตฌํ˜„
nuew
nuew
๐Ÿคธ ์žฌ์ฃผ ๋„˜๋Š” ์ค‘
  • nuew
    bloggg. . .๐Ÿฆ–๐Ÿ’ฅ
    nuew
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (88)
      • issue (10)
      • baekjoon (41)
      • lecture recap (11)
      • What I Learn (26)
      • retrospective (0)
      • maeil-mail (0)
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํ™ˆ
    • ํƒœ๊ทธ
    • ๋ฐฉ๋ช…๋ก
  • ๋งํฌ

  • ๊ณต์ง€์‚ฌํ•ญ

  • ์ธ๊ธฐ ๊ธ€

  • ํƒœ๊ทธ

    ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ
    media-query
    Algorithm
    TailwindCSS
    zustand
    ํ•œ์ž…ํฌ๊ธฐ๋กœ์ž˜๋ผ๋จน๋Š”ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ
    issue
    TypeScript
    what i learn
    JavaScript
    Study
    Baekjoon
    ํ•œ์ž…ํฌ๊ธฐ๋กœ ์ž˜๋ผ๋จน๋Š” ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ
    css
    ๋ฐฑ์ค€
    Node.js
    modal
    ์•Œ๊ณ ๋ฆฌ์ฆ˜
    ์ฝ”๋”ฉํ…Œ์ŠคํŠธ
    js
  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.3
nuew
Toast ์ ์šฉ๊ธฐ
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”