From 6c2fc019e712a1d2061729d92b84baa29d7473df Mon Sep 17 00:00:00 2001 From: dladncks1217 Date: Fri, 5 Jan 2024 16:14:39 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20StarRating=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StarRatingInput/StarRatingInput.style.ts | 4 +++ .../StarRatingInput/StarRatingInput.tsx | 21 ++++++++------ src/hooks/useDebounce.ts | 15 ++++++++++ src/hooks/useStarRatingInput.ts | 28 ++++++++++++------- 4 files changed, 49 insertions(+), 19 deletions(-) create mode 100644 src/hooks/useDebounce.ts diff --git a/src/components/StarRatingInput/StarRatingInput.style.ts b/src/components/StarRatingInput/StarRatingInput.style.ts index 840cbe5..d037bd2 100644 --- a/src/components/StarRatingInput/StarRatingInput.style.ts +++ b/src/components/StarRatingInput/StarRatingInput.style.ts @@ -13,3 +13,7 @@ export const inputContainerStyling = (size: number, gap: number) => { }, }); }; + +export const starItemStyling = css({ + cursor: 'pointer', +}); diff --git a/src/components/StarRatingInput/StarRatingInput.tsx b/src/components/StarRatingInput/StarRatingInput.tsx index a25bf27..e22d84f 100644 --- a/src/components/StarRatingInput/StarRatingInput.tsx +++ b/src/components/StarRatingInput/StarRatingInput.tsx @@ -6,7 +6,10 @@ import { forwardRef } from 'react'; import type { ForwardedRef } from 'react'; import Label from '@components/Label/Label'; -import { inputContainerStyling } from '@components/StarRatingInput/StarRatingInput.style'; +import { + inputContainerStyling, + starItemStyling, +} from '@components/StarRatingInput/StarRatingInput.style'; import SupportingText from '@components/SupportingText/SupportingText'; const STAR_RATING_EMPTY_LENGTH = 10; @@ -61,9 +64,9 @@ const StarRatingInput = ( onMouseOut={() => { if (!isMobile) onStarHoverOut(index); }} - key={Math.random()} + key={crypto.randomUUID()} > - + ); return ( @@ -78,9 +81,9 @@ const StarRatingInput = ( onMouseOut={() => { if (!isMobile) onStarHoverOut(index); }} - key={Math.random()} + key={crypto.randomUUID()} > - + ); } @@ -97,9 +100,9 @@ const StarRatingInput = ( onMouseOut={() => { if (!isMobile) onStarHoverOut(index); }} - key={Math.random()} + key={crypto.randomUUID()} > - + ); return ( @@ -114,9 +117,9 @@ const StarRatingInput = ( onMouseOut={() => { if (!isMobile) onStarHoverOut(index); }} - key={Math.random()} + key={crypto.randomUUID()} > - + ); })} diff --git a/src/hooks/useDebounce.ts b/src/hooks/useDebounce.ts new file mode 100644 index 0000000..c39c8e3 --- /dev/null +++ b/src/hooks/useDebounce.ts @@ -0,0 +1,15 @@ +import { useEffect, useState } from 'react'; + +export const useDebounce = (value: T, delay: number = 500): T => { + const [debouncedValue, setDebouncedValue] = useState(value); + + useEffect(() => { + const timer = setTimeout(() => setDebouncedValue(value), delay); + + return () => { + clearTimeout(timer); + }; + }, [value, delay]); + + return debouncedValue; +}; diff --git a/src/hooks/useStarRatingInput.ts b/src/hooks/useStarRatingInput.ts index 1cedcca..26220e3 100644 --- a/src/hooks/useStarRatingInput.ts +++ b/src/hooks/useStarRatingInput.ts @@ -1,12 +1,20 @@ -import { useCallback, useState } from 'react'; +import { useCallback, useRef, useState } from 'react'; + +import { useDebounce } from '@hooks/useDebounce'; type InitialRateType = 0 | 0.5 | 1 | 1.5 | 2 | 2.5 | 3 | 3.5 | 4 | 4.5 | 5; export const useStarRatingInput = (initialRate: InitialRateType, onClick?: CallableFunction) => { - const [starRate, setStarRate] = useState(initialRate); - const [hookStarRate, setHookStarRate] = useState(initialRate); - const [prevStarRate, setPrevStarRate] = useState(initialRate); - const [isHoveredBefore, setIsHoveredBefore] = useState(false); + const [tempStarRate, setStarRate] = useState(initialRate); + const starRate = useDebounce(tempStarRate, 50); + + const [tempHookStarRate, setHookStarRate] = useState(initialRate); + const hookStarRate = useDebounce(tempHookStarRate, 50); + + const [tempPrevStarRate, setPrevStarRate] = useState(initialRate); + const prevStarRate = useDebounce(tempPrevStarRate, 50); + + const hoverState = useRef(false); const handleStarClick = useCallback( (index: number) => { @@ -24,23 +32,23 @@ export const useStarRatingInput = (initialRate: InitialRateType, onClick?: Calla onClick?.(newRate); } }, - [hookStarRate, setHookStarRate, onClick] + [hookStarRate, onClick] ); const handleStarHover = useCallback((index: number) => { const newRate = ((index + 1) / 2) as InitialRateType; setStarRate(newRate); - setIsHoveredBefore(true); + hoverState.current = true; }, []); const handleStarHoverOut = useCallback(() => { - if (isHoveredBefore) { + if (hoverState.current) { setStarRate(prevStarRate as InitialRateType); } - setIsHoveredBefore(false); - }, [prevStarRate, isHoveredBefore]); + hoverState.current = false; + }, [prevStarRate]); return { starRate,