@@ -729,7 +729,7 @@ function Dashboard() {
729729
730730** Impact: MEDIUM (prevents memory leaks and redundant handlers)**
731731
732- Use ` @reactuses/core ` hooks for global events to prevent multiple subscriptions and ensure proper cleanup.
732+ Use ` ahooks ` hooks for global events to prevent multiple subscriptions and ensure proper cleanup.
733733
734734** Incorrect: each component creates its own listener**
735735
@@ -751,19 +751,22 @@ function Component2() {
751751}
752752```
753753
754- ** Correct: use @ reactuses/core hooks**
754+ ** Correct: use ahooks hooks**
755755
756756``` tsx
757- import { useEventListener , useWindowSize } from ' @reactuses/core '
757+ import { useEventListener } from ' ahooks '
758758
759759// Option 1: Listen to resize event directly
760760function Component1() {
761761 useEventListener (' resize' , () => console .log (' resize' ))
762762}
763763
764- // Option 2: Get window dimensions reactively
764+ // Option 2: Get window dimensions reactively with useEventListener
765765function Component2() {
766- const { width, height } = useWindowSize ()
766+ const [size, setSize] = useState ({ width: 0 , height: 0 })
767+ useEventListener (' resize' , () => {
768+ setSize ({ width: window .innerWidth , height: window .innerHeight })
769+ })
767770 // Automatically updates on resize
768771}
769772```
@@ -889,7 +892,7 @@ function Profile({ user }: { user: User }) {
889892
890893** Impact: MEDIUM (reduces re-render frequency)**
891894
892- Subscribe to derived boolean state instead of continuous values to reduce re-render frequency. Use ` useMediaQuery ` from ` @reactuses/core ` .
895+ Subscribe to derived boolean state instead of continuous values to reduce re-render frequency. Use ` useResponsive ` from ` ahooks ` .
893896
894897** Incorrect: re-renders on every pixel change**
895898
@@ -901,18 +904,19 @@ function Sidebar() {
901904}
902905```
903906
904- **Correct: re-renders only when boolean changes**
907+ **Correct: re-renders only when breakpoint changes**
905908
906909```tsx
907- import { useMediaQuery } from '@reactuses/core '
910+ import { useResponsive } from 'ahooks '
908911
909912function Sidebar() {
910- const isMobile = useMediaQuery (' (max-width: 767px)' )
913+ const responsive = useResponsive ()
914+ const isMobile = ! responsive .md // md breakpoint is 768px by default
911915 return <nav className = { isMobile ? ' mobile' : ' desktop' } >
912916}
913917```
914918
915- `useMediaQuery ` uses `useSyncExternalStore` internally for optimized re-rendering and only triggers updates when the query match state changes.
919+ `useResponsive ` uses breakpoint-based updates and only triggers re-renders when the breakpoint state changes, not on every pixel .
916920
917921### 5.5 Use Functional setState Updates
918922
@@ -1050,7 +1054,7 @@ For simple primitives (`useState(0)`), direct references (`useState(props.value)
10501054
10511055**Impact: MEDIUM (maintains UI responsiveness)**
10521056
1053- Mark frequent, non-urgent state updates as transitions to maintain UI responsiveness. Alternatively, use throttling from `@reactuses/core `.
1057+ Mark frequent, non-urgent state updates as transitions to maintain UI responsiveness. Alternatively, use throttling from `ahooks `.
10541058
10551059**Incorrect: blocks UI on every scroll**
10561060
@@ -1082,18 +1086,16 @@ function ScrollTracker() {
10821086}
10831087```
10841088
1085- **Alternative: throttling with @reactuses/core **
1089+ **Alternative: throttling with ahooks **
10861090
10871091```tsx
1088- import { useEventListener , useThrottle } from '@reactuses/core '
1092+ import { useEventListener , useThrottle } from 'ahooks '
10891093
10901094function ScrollTracker() {
10911095 const [scrollY , setScrollY ] = useState (0 )
1092- const throttledScrollY = useThrottle (scrollY , 100 ) // Update max 10x/sec
1096+ const throttledScrollY = useThrottle (scrollY , { wait: 100 } ) // Update max 10x/sec
10931097
1094- useEventListener (' scroll' , () => setScrollY (window .scrollY ), {
1095- passive: true
1096- })
1098+ useEventListener (' scroll' , () => setScrollY (window .scrollY ))
10971099
10981100 // Use throttledScrollY for rendering
10991101 return <div >Scroll: { throttledScrollY } px</div >
@@ -1929,7 +1931,7 @@ Advanced patterns for specific cases that require careful implementation.
19291931
19301932**Impact: LOW (stable subscriptions)**
19311933
1932- Store callbacks in refs when used in effects that shouldn't re-subscribe on callback changes. Prefer `@reactuses/core ` hooks which handle this internally.
1934+ Store callbacks in refs when used in effects that shouldn't re-subscribe on callback changes. Prefer `ahooks ` hooks which handle this internally.
19331935
19341936**Incorrect: re-subscribes on every render**
19351937
@@ -1942,10 +1944,10 @@ function useWindowEvent(event: string, handler: () => void) {
19421944}
19431945```
19441946
1945- **Correct: use @reactuses/core useEventListener**
1947+ **Correct: use ahooks useEventListener**
19461948
19471949```tsx
1948- import { useEventListener } from '@reactuses/core '
1950+ import { useEventListener } from 'ahooks '
19491951
19501952function Component() {
19511953 // Handler is stored in a ref internally - no re-subscription on handler change
@@ -1976,7 +1978,7 @@ function useWindowEvent(event: string, handler: () => void) {
19761978
19771979**Impact: LOW (prevents effect re-runs)**
19781980
1979- Access latest values in callbacks without adding them to dependency arrays. Prevents effect re-runs while avoiding stale closures. Use `useLatest` from `@reactuses/core `.
1981+ Access latest values in callbacks without adding them to dependency arrays. Prevents effect re-runs while avoiding stale closures. Use `useLatest` from `ahooks `.
19801982
19811983**Incorrect: effect re-runs on every callback change**
19821984
@@ -1991,10 +1993,10 @@ function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
19911993}
19921994```
19931995
1994- **Correct: stable effect, fresh callback with @reactuses/core **
1996+ **Correct: stable effect, fresh callback with ahooks **
19951997
19961998```tsx
1997- import { useLatest } from '@reactuses/core '
1999+ import { useLatest } from 'ahooks '
19982000
19992001function SearchInput({ onSearch } : { onSearch : (q : string ) => void } ) {
20002002 const [query , setQuery ] = useState (' ' )
@@ -2007,24 +2009,24 @@ function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
20072009}
20082010```
20092011
2010- **Alternative: use useDebounce for this specific pattern**
2012+ **Alternative: use useDebounceFn for this specific pattern**
20112013
20122014```tsx
2013- import { useDebounce } from '@reactuses/core '
2015+ import { useDebounceFn } from 'ahooks '
20142016
20152017function SearchInput({ onSearch } : { onSearch : (q : string ) => void } ) {
20162018 const [query , setQuery ] = useState (' ' )
2017- const debouncedQuery = useDebounce ( query , 300 )
2019+ const { run: debouncedSearch } = useDebounceFn ( onSearch , { wait: 300 } )
20182020
20192021 useEffect (() => {
2020- if (debouncedQuery ) {
2021- onSearch ( debouncedQuery )
2022+ if (query ) {
2023+ debouncedSearch ( query )
20222024 }
2023- }, [debouncedQuery , onSearch ])
2025+ }, [query , debouncedSearch ])
20242026}
20252027```
20262028
2027- For debounced search specifically, `useDebounce ` provides a cleaner solution.
2029+ For debounced search specifically, `useDebounceFn ` provides a cleaner solution.
20282030
20292031---
20302032
@@ -2034,5 +2036,5 @@ For debounced search specifically, `useDebounce` provides a cleaner solution.
203420362. [https://nextjs.org](https://nextjs.org)
203520373. [https://tanstack.com/query](https://tanstack.com/query)
203620384. [https://github.com/shuding/better-all](https://github.com/shuding/better-all)
2037- 5. [https://reactuse.com ](https://reactuse.com ) - @reactuses/core hooks library
2039+ 5. [https://ahooks.js.org ](https://ahooks.js.org ) - ahooks React hooks library
20382040
0 commit comments