elements
lifecycle
browser
- useAudio
- useBattery
- useBluetooth
- useBreakpoints
- useBroadcastChannel
- useBrowserLocation
- useClipboard
- useCopy
- useCssVar
- useDisplayMedia
- useDocumentEvent
- useDocumentTitle
- useDocumentVisibility
- useEventListener
- useEventSource
- useEyeDropper
- useFavicon
- useFileSystemAccess
- useFps
- useFullscreen
- useGamepad
- useGeolocation
- useMeasure
- useMediaControls
- useMediaQuery
- useMemory
- useNetwork
- useObjectUrl
- useOnline
- useOtpCredential
- usePermission
- usePictureInPicture
- usePointerLock
- usePostMessage
- useRaf
- useShare
- useSpeechRecognition
- useSpeechSynthesis
- useSticky
- useVibrate
- useVirtualKeyboard
- useWakeLock
- useWebSocket
utilities
state
- useBoolean
- useControllableState
- useCookie
- useCookies
- useCounter
- useCycleList
- useDefault
- useDisclosure
- useField
- useHash
- useList
- useLocalStorage
- useMap
- useMask
- useMergedRef
- useObject
- useOffsetPagination
- useQueue
- useRafState
- useRefState
- useSessionStorage
- useSet
- useStateHistory
- useStep
- useStorage
- useToggle
- useUrlSearchParam
- useUrlSearchParams
- useValidatedState
- useWizard
user
sensors
- useDeviceMotion
- useDeviceOrientation
- useHotkeys
- useIdle
- useInfiniteScroll
- useIntersectionObserver
- useKeyboard
- useKeyPress
- useKeysPressed
- useMouse
- useMutationObserver
- useOrientation
- usePageLeave
- useParallax
- usePerformanceObserver
- useResizeObserver
- useScroll
- useScrollIntoView
- useScrollTo
- useSwipe
- useTextSelection
- useVisibility
- useWindowEvent
- useWindowFocus
- useWindowScroll
- useWindowSize
Jun 26, 2026, 07:11:34
EUR/USDEuro / US Dollar
import { usePrevious, useQuery } from '@siberiacancode/reactuse';
import { ArrowDownIcon, ArrowUpIcon } from 'lucide-react';
import { cn } from '@/utils/lib';
const fetchRate = async () => {
await new Promise((resolve) => setTimeout(resolve, 600));
return Number((1.05 + (Math.random() - 0.5) * 0.04).toFixed(4));
};
const Demo = () => {
const rateQuery = useQuery(fetchRate, { refetchInterval: 2000 });
const previousRate = usePrevious(rateQuery.data);
const price = rateQuery.data;
const diff = price !== undefined && previousRate !== undefined ? price - previousRate : 0;
const up = diff >= 0;
const percent = previousRate ? (diff / previousRate) * 100 : 0;
const formattedDate = new Intl.DateTimeFormat('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
}).format(new Date());
return (
<section className='flex w-full justify-center p-6'>
<div className='bg-card flex w-full max-w-xs flex-col gap-4 rounded-xl p-5'>
<span className='text-muted-foreground text-xs tabular-nums'>{formattedDate}</span>
<div className='flex items-center justify-between gap-3'>
<div className='flex h-9 items-center'>
{rateQuery.isLoading && <div className='bg-muted h-9 w-32 animate-pulse rounded-md' />}
{!rateQuery.isLoading && !!price && (
<span className='text-foreground font-mono text-3xl leading-none font-bold tabular-nums'>
{price.toFixed(4)}
</span>
)}
</div>
<div className='flex h-7 items-center'>
{rateQuery.isLoading && <div className='bg-muted h-7 w-16 animate-pulse rounded-md' />}
{!rateQuery.isLoading && !!price && (
<div
className={cn(
'flex h-7 items-center gap-1 rounded-md px-2 py-1 text-sm font-semibold tabular-nums',
up
? 'bg-green-500/10 text-green-600 dark:text-green-500'
: 'bg-destructive/10 text-destructive'
)}
>
{up ? <ArrowUpIcon className='size-3.5' /> : <ArrowDownIcon className='size-3.5' />}
{percent >= 0 ? '+' : ''}
{percent.toFixed(2)}%
</div>
)}
</div>
</div>
<div className='flex items-center gap-2'>
<span className='text-foreground text-sm font-semibold'>EUR/USD</span>
<span className='text-muted-foreground text-xs'>Euro / US Dollar</span>
</div>
</div>
</section>
);
};
export default Demo;
Installation
pnpm add @siberiacancode/reactuseUsage
const prevValue = usePrevious(value);Type Declarations
export interface UsePreviousOptions<Value> {
equality: (a: Value, b: Value) => boolean;
}API
Parameters
| Name | Type | Default | Note |
|---|---|---|---|
| value | Value | - | The value to get the previous value |
| options.equality | (a: Value, b: Value) => boolean | - | The custom equality function to determine if the value has changed |
Returns
Value | undefinedContributors
ddebabinbbabinhhywax
Last updated on