Skip to content

Commit

Permalink
dApp: Points - implement claim function debounce (#783)
Browse files Browse the repository at this point in the history
Closes: #739 

There was an issue user was able to click the button multiple times
before the modal was displayed causing the claim action to be executed
multiple times. it led to multiple points logs registered in the
database.

As the solution i applied debounce technique to limit calls of the
`claimPoints` function.
  • Loading branch information
kkosiorowska authored Nov 6, 2024
2 parents ea5e462 + 54a9f37 commit a843eae
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
23 changes: 23 additions & 0 deletions dapp/src/hooks/useDebounce.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useCallback, useRef } from "react"

/**
* Debounce a function
* @param callback The function to debounce
* @param delay The delay in ms
* @returns A debounced function
*/
export default function useDebounce(callback: VoidFunction, delay = 250) {
const latestTimeout = useRef<NodeJS.Timeout>()

const memoizedCallback = useCallback(callback, [callback])

return () => {
if (latestTimeout.current) {
clearTimeout(latestTimeout.current)
}

latestTimeout.current = setTimeout(() => {
memoizedCallback()
}, delay)
}
}
5 changes: 4 additions & 1 deletion dapp/src/pages/DashboardPage/AcrePointsCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { useAcrePoints } from "#/hooks"
import Spinner from "#/components/shared/Spinner"
import { IconInfoCircle } from "@tabler/icons-react"
import UserDataSkeleton from "#/components/shared/UserDataSkeleton"
import useDebounce from "#/hooks/useDebounce"

export default function AcrePointsCard(props: CardProps) {
const {
Expand All @@ -30,6 +31,8 @@ export default function AcrePointsCard(props: CardProps) {
isCalculationInProgress,
} = useAcrePoints()

const debouncedClaimPoints = useDebounce(claimPoints, 1000)

const formattedTotalPointsAmount = numberToLocaleString(totalBalance)
const formattedClaimablePointsAmount = numberToLocaleString(claimableBalance)

Expand Down Expand Up @@ -101,7 +104,7 @@ export default function AcrePointsCard(props: CardProps) {
{claimableBalance && (
<Button
mt={3}
onClick={claimPoints}
onClick={debouncedClaimPoints}
w="full"
colorScheme="green"
color="gold.200"
Expand Down

0 comments on commit a843eae

Please sign in to comment.