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,