Skip to content

Commit cbc25d2

Browse files
committed
feat: 🎸 Major update
1 parent f005932 commit cbc25d2

File tree

24 files changed

+244
-55
lines changed

24 files changed

+244
-55
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,28 @@ yarn add @better-hooks/performance
5959

6060
## Examples
6161

62+
#### useDeepEffect
63+
64+
This hook deeply compares the dependencies optimizing rerendering effects
65+
66+
```tsx
67+
import React from "react";
68+
import { useDebounce } from "@better-hooks/performance";
69+
70+
const MyComponent: React.FC = () => {
71+
const {debounce, reset, active} = useDeepEffect(() => {
72+
// do something
73+
}, [{a: 123}]) // <--- we will check if the deps are equal between rerenders
74+
75+
return (
76+
// ...
77+
)
78+
}
79+
80+
```
81+
82+
---
83+
6284
#### useDebounce
6385

6486
This hook allows debouncing of the given function. Function will be called after some amount of time

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,5 +122,8 @@
122122
"useThrottle",
123123
"useThrottleState",
124124
"useThrottleEffect"
125-
]
125+
],
126+
"dependencies": {
127+
"@better-hooks/lifecycle": "^1.1.2"
128+
}
126129
}

src/constants/browser.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export const isBrowser = !!(
2+
typeof window !== "undefined" &&
3+
typeof window.document !== "undefined" &&
4+
typeof window.document.createElement !== "undefined"
5+
);

src/hooks/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
export * from "./use-debounce";
2-
export * from "./use-debounce-state";
32
export * from "./use-debounce-effect";
3+
export * from "./use-debounce-state";
4+
export * from "./use-deep-effect";
5+
export * from "./use-interval";
46
export * from "./use-throttle";
5-
export * from "./use-throttle-state";
67
export * from "./use-throttle-effect";
8+
export * from "./use-throttle-state";
9+
export * from "./use-timeout";
10+
export * from "./use-isomorphic-effect";

src/hooks/use-debounce-effect/use-debounce-effect.hook.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/* eslint-disable react-hooks/exhaustive-deps */
22
import { useEffect } from "react";
33

4-
import { useDebounce } from "hooks/use-debounce/use-debounce.hook";
5-
import { UseDebounceProps } from "hooks/use-debounce/use-debounce.types";
4+
import { useDebounce, UseDebounceProps } from "hooks";
65

6+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
77
export const useDebounceEffect = (
88
callback: () => void,
99
props: UseDebounceProps,
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { useState } from "react";
22

3-
import { useDebounce } from "hooks/use-debounce/use-debounce.hook";
4-
import { UseDebounceProps } from "hooks/use-debounce/use-debounce.types";
3+
import { useDebounce, UseDebounceProps } from "hooks";
54

65
export const useDebounceState = <T>(initialValue: T, props?: UseDebounceProps) => {
76
const { debounce } = useDebounce(props);
87
const [value, setValue] = useState(initialValue);
9-
return [value, (newValue: Parameters<typeof setValue>[0]) => debounce(() => setValue(newValue))];
8+
return [
9+
value,
10+
(newValue: Parameters<typeof setValue>[0]) => debounce(() => setValue(newValue)),
11+
] as const;
1012
};

src/hooks/use-debounce/use-debounce.hook.ts

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,36 @@
1-
import { useEffect, useRef } from "react";
1+
import { useCallback, useEffect, useRef } from "react";
2+
import { useForceUpdate } from "@better-hooks/lifecycle";
23

3-
import {
4-
DebounceType,
5-
UseDebounceProps,
6-
DebounceFunctionType,
7-
UseDebounceReturnType,
8-
} from "./use-debounce.types";
9-
import { useForceUpdate } from "hooks/use-force-update";
4+
import { DebounceType, UseDebounceProps, DebounceFunctionType, UseDebounceReturnType } from "hooks";
105

116
export const useDebounce = (props?: UseDebounceProps): UseDebounceReturnType => {
127
const { delay = 400 } = props || {};
138
const shouldRerenderActive = useRef(false);
149
const timer = useRef<DebounceType>(null);
1510
const forceUpdate = useForceUpdate();
1611

17-
const rerenderActive = () => {
12+
const rerenderActive = useCallback(() => {
1813
if (shouldRerenderActive.current) forceUpdate();
19-
};
14+
}, [forceUpdate]);
2015

2116
const reset = () => {
2217
if (timer.current !== null) clearTimeout(timer.current);
2318
timer.current = null;
2419
};
2520

26-
const debounce: DebounceFunctionType = (callback, dynamicDelay) => {
27-
const time = dynamicDelay ?? delay;
28-
reset();
29-
timer.current = setTimeout(() => {
30-
timer.current = null;
31-
callback();
21+
const debounce: DebounceFunctionType = useCallback(
22+
(callback, dynamicDelay) => {
23+
const time = dynamicDelay ?? delay;
24+
reset();
25+
timer.current = setTimeout(() => {
26+
timer.current = null;
27+
callback();
28+
rerenderActive();
29+
}, time);
3230
rerenderActive();
33-
}, time);
34-
rerenderActive();
35-
};
31+
},
32+
[delay, rerenderActive],
33+
);
3634

3735
useEffect(() => {
3836
return reset;

src/hooks/use-debounce/use-debounce.types.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
export type DebounceType = ReturnType<typeof setTimeout> | null;
22

3-
export type DebounceFunctionType = (
4-
callback: () => void | Promise<void>,
5-
dynamicDelay?: number,
6-
) => void;
3+
export type DebounceFunctionType = (callback: () => void | Promise<void>, dynamicDelay?: number) => void;
74

85
export type UseDebounceReturnType = {
96
debounce: DebounceFunctionType;

src/hooks/use-deep-effect/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./use-deep-effect.hook";
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* eslint-disable react-hooks/rules-of-hooks */
2+
/* eslint-disable react-hooks/exhaustive-deps */
3+
import { useEffect, useMemo, useRef } from "react";
4+
5+
import { isEqual } from "./use-deep-effect.utils";
6+
7+
const memo = (value: any) => {
8+
const ref = useRef(value);
9+
const changed = useRef<number>(0);
10+
11+
if (!isEqual(value, ref.current)) {
12+
ref.current = value;
13+
changed.current += 1;
14+
}
15+
16+
return useMemo(() => ref.current, [changed.current]);
17+
};
18+
19+
export const useDeepEffect = (
20+
callback: VoidFunction | (() => VoidFunction),
21+
dependencies: any[],
22+
) => {
23+
return useEffect(callback, memo(dependencies));
24+
};

0 commit comments

Comments
 (0)