diff --git a/src/components/CountdownExample.jsx b/src/components/CountdownExample.jsx index e057f19..85228aa 100644 --- a/src/components/CountdownExample.jsx +++ b/src/components/CountdownExample.jsx @@ -1,31 +1,8 @@ -import { useState, useEffect } from "react"; +import { useCountdown } from "../hooks/useCountdown"; export const CountdownExample = () => { const targetDate = new Date("2025-08-25T00:00:00"); - - const calculateTimeLeft = (targetDate) => { - const difference = targetDate.getTime() - new Date().getTime(); - - if (difference <= 0) { - return { days: 0, hours: 0, minutes: 0, seconds: 0 }; - } - - const days = Math.floor(difference / (1000 * 60 * 60 * 24)); - const hours = Math.floor((difference / (1000 * 60 * 60)) % 24); - const minutes = Math.floor((difference / (1000 * 60)) % 60); - const seconds = Math.floor((difference / 1000) % 60); - - return { days, hours, minutes, seconds }; - }; - const [timeLeft, setTimeLeft] = useState(() => calculateTimeLeft(targetDate)); - - useEffect(() => { - const timer = setInterval(() => { - setTimeLeft(calculateTimeLeft(targetDate)); - }, 1000); - - return () => clearInterval(timer); - }, [targetDate]); + const timeLeft = useCountdown(targetDate); return (
diff --git a/src/components/WindowSizeExample.jsx b/src/components/WindowSizeExample.jsx index 8a4c768..6b142fe 100644 --- a/src/components/WindowSizeExample.jsx +++ b/src/components/WindowSizeExample.jsx @@ -1,26 +1,8 @@ -import { useEffect, useState } from "react"; +import { useWindowSize } from "../hooks/useWindowSize"; export const WindowSizeExample = () => { // 실습 1. 하단 코드를 useWindowSize (커스텀 훅으로 바꿔주세요!) - const [windowSize, setWindowSize] = useState({ - width: window.innerWidth, - height: window.innerHeight, - }); - - useEffect(() => { - const handleResize = () => { - setWindowSize({ - width: window.innerWidth, - height: window.innerHeight, - }); - }; - - window.addEventListener("resize", handleResize); - - return () => { - window.removeEventListener("resize", handleResize); - }; - }, []); + const { windowSize } = useWindowSize(); return (
diff --git a/src/components/YourOwnHookPage.jsx b/src/components/YourOwnHookPage.jsx index ee5502f..424e64f 100644 --- a/src/components/YourOwnHookPage.jsx +++ b/src/components/YourOwnHookPage.jsx @@ -1,11 +1,15 @@ -import { useSomething } from "../hooks/useSomething"; +import { useName } from "../hooks/useMyName"; export const YourOwnHookPage = () => { - // const { something... } = useSomething(); - // 하단 UI에 자유롭게 위에서 받아온 값들을 바인딩 해보세요~ + const { name, changeName } = useName(); + return (

useSomething 실습

+

{name}

+
); }; diff --git a/src/hooks/useConfetti.js b/src/hooks/useConfetti.js index 662f311..ecf9592 100644 --- a/src/hooks/useConfetti.js +++ b/src/hooks/useConfetti.js @@ -8,5 +8,16 @@ export const useConfetti = () => { origin: { y: 0.6 }, }); }; - return { fire }; + + const fire2 = () => { + confetti({ + particleCount: 100, + spread: 360, + origin: { + x: Math.random(), + y: Math.random() - 0.2, + }, + }); + }; + return { fire, fire2 }; }; diff --git a/src/hooks/useCountdown.js b/src/hooks/useCountdown.js index 19c04c3..156f352 100644 --- a/src/hooks/useCountdown.js +++ b/src/hooks/useCountdown.js @@ -1,3 +1,15 @@ +import { useEffect, useState } from "react"; +import { calculateTimeLeft } from "../utils/calculateTime"; + export const useCountdown = (targetDate) => { + const [timeLeft, setTimeLeft] = useState(() => calculateTimeLeft(targetDate)); + + useEffect(() => { + const timer = setInterval(() => { + setTimeLeft(calculateTimeLeft(targetDate)); + }, 1000); + + return () => clearInterval(timer); + }, [targetDate]); return timeLeft; }; diff --git a/src/hooks/useMyName.js b/src/hooks/useMyName.js new file mode 100644 index 0000000..d713221 --- /dev/null +++ b/src/hooks/useMyName.js @@ -0,0 +1,23 @@ +import { useEffect, useState } from "react"; +import { useConfetti } from "./useConfetti"; + +export const useName = () => { + // 여러분의 use{name}을 만들어주세요! + // 정답은 없습니다. 커스텀훅의 필요성을 스스로 느껴보세요. + // 아이디어를 생각하고, 스스로 구현하다가 어려우면 손 들어주세요! + const [name, setName] = useState("아기사자"); + const { fire2 } = useConfetti(); + + const changeName = () => { + setName((prev) => (prev === "아기사자" ? "아기사자 백지연" : "아기사자")); + }; + + useEffect(() => { + fire2(); + }, [name]); + + return { + name, + changeName, + }; +}; diff --git a/src/hooks/useSomething.js b/src/hooks/useSomething.js deleted file mode 100644 index 48815a1..0000000 --- a/src/hooks/useSomething.js +++ /dev/null @@ -1,5 +0,0 @@ -export const useSomething = () => { - // 여러분의 use{Something}을 만들어주세요! - // 정답은 없습니다. 커스텀훅의 필요성을 스스로 느껴보세요. - // 아이디어를 생각하고, 스스로 구현하다가 어려우면 손 들어주세요! -}; diff --git a/src/hooks/useWindowSize.js b/src/hooks/useWindowSize.js index 28d9f7c..9b26359 100644 --- a/src/hooks/useWindowSize.js +++ b/src/hooks/useWindowSize.js @@ -1 +1,27 @@ +import { useEffect, useState } from "react"; + + // 커스텀훅 코드를 작성해보세요! +export const useWindowSize = () => { + const [windowSize, setWindowSize] = useState({ + width: window.innerWidth, + height: window.innerHeight, + }); + + useEffect(() => { + const handleResize = () => { + setWindowSize({ + width: window.innerWidth, + height: window.innerHeight, + }); + }; + + window.addEventListener("resize", handleResize); + + return () => { + window.removeEventListener("resize", handleResize); + }; + }, []); + + return { windowSize }; +}; diff --git a/src/utils/calculateTime.js b/src/utils/calculateTime.js new file mode 100644 index 0000000..c7caa7f --- /dev/null +++ b/src/utils/calculateTime.js @@ -0,0 +1,14 @@ +export const calculateTimeLeft = (targetDate) => { + const difference = targetDate.getTime() - new Date().getTime(); + + if (difference <= 0) { + return { days: 0, hours: 0, minutes: 0, seconds: 0 }; + } + + const days = Math.floor(difference / (1000 * 60 * 60 * 24)); + const hours = Math.floor((difference / (1000 * 60 * 60)) % 24); + const minutes = Math.floor((difference / (1000 * 60)) % 60); + const seconds = Math.floor((difference / 1000) % 60); + + return { days, hours, minutes, seconds }; +};